Chapter 3
De ikke objekt-orienterede dele af Java

Kurt Nørmark ©
Department of Computer Science, Aalborg University, Denmark


September 2001


Abstract
Previous lecture Next lecture
Index References Contents
I denne lektion vil vi studere de dele af Java, som ikke er snævert forbundet med objekt-orienteret programmering. Dette er primitive datatyper, erklæringer, kommandoer, kontrolstrukturer, udtryk, operatorer, herunder operator prioriteringer. Vi ser også på simpel input og output.


Datatyper i Java

Primitive Datatyper i Java: taltyper
Slide Note Contents Index
References Speak
Vi starter med at studere de datatyper, som kan bruges umiddelbart i ethvert Java program. Vi kalder dem primitive i modsætning til typer baseret på klasser, som vi er meget optaget af i forbindelse med objekt-orienteret programmering

De primitive data er ikke-muterbare værdier i modsætning til objekter

  • Heltal

    • byte   8 bits

    • short   16 bits

    • int   32 bits

    • long   64 bits

  • Reelle tal

    • float   32 bits

    • double   64 bits

Det er værd at bemærke at alle heltal og reelle tal har en fast størrelse på tværs af platformene, hvor Java er implementeret. Eksempelvis er int typen 32 bits heltal både på Unix og Mac.

Heltal af typen long noteres med et efterstillet 'L'. Eksempelvis er 123L altså tallet 123 som en long. Hvis det efterstillede 'L' ikke forekommer er der tale om en værdi i int.

Java tillader os at notere heltal i basis 8 (oktal), 10 (decimal) og 16 (hexadecimal). Et foranstillet '0' angiver oktal basis, og et foranstillet '0X' angiver hexademinal basis. Eksempelvis er tallet 011 altså lig med 9 (decimalt), og tallet 0X11 er lig med 17 (decimalt). Oktal og hexadecimal notation er praktisk hvis man arbejder direkte med bit, idet et oktalt eller hexadecimalt tal direkte kan transformeres til binær repræsentation ved ciffervis konvertering. (Dette er meget mere besværligt at konvertere et decimalt tal til binær repræsentation).

Man kan observere, at Java understøtter regning med heltal af vilkårlig stor præcision via klassen BigInteger - jf. referencen fra denne side.

Typerne double og float har samme leksikalske syntaks. Som eksempler kan nævnes

    7.51 5. .5 3.14 1e-19 2e97

Hvis ikke andet angives er tallet en double (default). Hvis man ønsker at notere et tal af typen float skal man afslutte tallet med et f. Så følgende er eksempler på værdier i typen float:

    7.51f 5.f .5f 3.14f 1e-19f 2e97f

Symmetrisk kan man også angive et d tilsidst - d for double. Men det er altså ikke nødvendigt

References

Program: Et Java program som erklærer to int, tre long og en float variabel. Programmet udskriver tallene 10, 18, 9, 17, 2748 og 3100.0
class TalEksempel {

  static int i = 012;
  static int j = 0X12;

  static long n = 011L;
  static long m = 0X11L;

  static long p = 0XabcL;

  static float f = 31e2f;

  public static void main(String[] args){
    System.out.println("i = " + i);
    System.out.println("j = " + j);

    System.out.println("n = " + n);
    System.out.println("m = " + m);

    System.out.println("p = " + p);

    System.out.println("f = " + f);
  }
}

Primitive Datatyper i Java: boolean og tegn
Slide Note Contents Index
References Speak

  • Boolean

    • boolean

    • Typen indeholder værdierne true og false

  • Tegn

    • char

    • Værdierne i char er tal - char er altså en numerisk type

    • Unicode tegnsættet, hvoraf ASCII tegnsættet er en delmængde

    • Værdier i enkelt-quotes, såsom 'a'

    • Escape sekvenser, såsom '\u0061' og '\141' (begge tegnet 'a')

Der er kun direkte og naturlig notation for en delmængde af de første 128 tegn i Unicode alfabetet. Denne naturlige notation udgøres af symboler i fonte. På inputsiden spiller tastaturets udformning naturligvis også en rolle. De første 128 tegn i Unicode alfabetet er sammenfaldende med det velkendte, basale ASCII alfabet (det udvidere ASCII alfabet udgøres - som bekendt - af 256 tegn). Som i andre sprog i C-familien virker escape tegnene \b, \t, \n, , \f og \r for tegnene hhv. 8, 9, 10, 12, og 13 i ASCII tegnsættet. Endvidere kan man benyttet backslash tegnet for at kunne notere quote tegnene og backslash selv:\', \", \\. De første 256 tegn kan noteres som \abc, hvor a, b og c er octale cifre (a dog kun 0-3). Endelig kan et vilkårligt tegn i det store unicode tegnsæt noteres som \uxxxx, hvor x er et hexadecimalt ciffer: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, a, b, c, d, e eller f. Herunder er der et antal referencer til Java Sprogspecifikationen, som giver alle detaljer om tegn i Java.

References

Klasser som repræsenterer primitive typer
Slide Note Contents Index
References Speak

Der findes objekter, som udgør alternative repræsentationer af værdierne i de primitive typer

  • Klasser der repræsenterer værdityper

    • Wrapper klasserne

      • Boolean

      • Byte

      • Character

      • Double

      • Float

      • Integer

      • Long

    • Klassen BigInteger som kan repræsentere vilkårligt store tal

Program: En klasse som repræsenterer en brøk ved brug af BigInteger objekter. Et sådant objekt er også kendt som et rationelt tal. Vi interesserer os her og nu for BigInteger operationerne i klassen.
import java.math.*;

public class Broek{

private BigInteger tæller, nævner;

  public Broek (BigInteger tæller, BigInteger nævner){
      BigInteger divisor; 
      if (nævner.equals(BigInteger.ZERO)) 
        throw new RuntimeException("Nævneren er 0");
      divisor = tæller.gcd(nævner);
      this.tæller = tæller.divide(divisor);
      this.nævner = nævner.divide(divisor);
  }

  public String toString(){
    return "Broek: " + tæller + "/" + nævner;
  } 


 /* Demo */
 public static void main(String[] args){
   BigInteger n = new BigInteger("12345678912345678912345678912345678912345678900");
   BigInteger m = new BigInteger("555555555555555555555555555555");
   
   Broek b = new Broek(n,m);

   System.out.println("b er " + b);
 }

}

 
  


Exercise 3.1. Klassen BrøkProgrammer videre på klassen Broek, som vi har startet på ovenfor.

Programmer som et minimum de aritmetiske operationer add, subtract, multiply og divide.

Programmer også gerne andre relevante operationer, såsom equals, less-than, osv. Hvis du laver equals metoden bør du erindre mønstret fra en tidligere lektion.

References

Sammensatte datatyper i Java: Arrays
Slide Note Contents Index
References Speak
Det er naturligt at spørge, hvordan Java håndterer sammensatte datatyper - altså datastrukturer. Som en vigtig del af 'sædvanlige' programmeringsprog findes der forskellige datastrukturer, såsom arrays, records, sets, mv. I Java bliver alle typer, som svarer til sådanne datastrukturer, realiseret som abstrakte datatyper, og implementeret som klasser.

I Java defineres datastrukturer som klasser i Java klassebiblioteket

  • Array typer

    • Et array er en indiceret sekvens af værdier af samme type med effektiv tilgang.

    • Eksempel på array-erklæring:

      • boolean[] tabel = new boolean [MAXINDEX];

      • Element type: Boolean

      • Indekstypen: Altid af typen int

      • Indeksgrænser: 0 .. MAXINDEX-1

    • Vi vender tilbage til arrays og collections i en senere lektion

I array eksemplet er tabel et objekt, som instantieres på en særlig array-specifik måde. Det første element i et array har altid indeks 0. Ovenstående eksempel svarer til Pascal erklæringen:

    tabel: array[0 .. MAXINDEX-1] of boolean
Det kan forekomme uheldig at man har taget særligt, syntaktisk hensyn til arrays i Java. Principielt kunne arrays håndteres som enhver anden datatype - implementeret som en klasse. Bevæggrunden for særbehandlingen er dog klar nok: at gøre arrays effektive i sproget.

I mange sammenhænge vil en Java programmør bruge andre typer end Array, hvis man ønsker at at arbejde med samlinger af data. Java understøtter et Collection begreb, som er på et langt højere abstraktionsniveau end arrays. Mere om dette i en senere lektion.

Ofte opfattes strenge som en særlig type af arrays. I Java er strenge objekter af typen String. Dog er der ligesom ved arrays særlig sproglig understøttelse af strings i Java. I en senere lektion ser vi nærmere på strenge i java.

References

Sammensatte datatyper i Java: Records
Slide Note Contents Index
References Speak
I forlængelse af forrige side ser vi her på recordbegrebet.

  • Record typer

    • En record er en navngivet mængde af værdier af forskellige typer med effektiv tilgang.

    • Enhver klasse med instansvariable kan opfattes som en record type.

    • Klassebegrebet kan opfattes som et generaliseret recordbegreb

Reference

I bibliotekerne til Java findes der klasser svarende til mange andre, specialiserede datastrukturer end arrays og records.Vi møder nogle af disse senere på kurset. Andre studeres i kurset Algoritmik

Erklæringer i Java
Slide Note Contents Index
References Speak
Erklæringer i Java er specielle på flere områder i forhold til Pascal. Vi ser nu nærmere på dette

The concept erklæring: I en erklæring introduceres et navn, samt en række egenskaber af et navnI nogle programmeringssprog er det ikke nødvendigt at introducere et navn via en erklæring. Man kan blot bruge det. Java er dog ikke et sådant sprog. Ligesom i Pascal, skal vi erklære et navn før vi kan bruge det. Man kan for eksempel ikke blot assigne til en variabel uden først at have introduceret variablen i en erklæring.

Syntax: Efter typen angives en liste af komma separerede variabelnavne. Hvert af disse navne erklæres til at være af den angivne type

type variabel1, variabel2, ..., variabeln;

Syntax: Som en variation er det muligt at angive udtryk, der beregnes til variablenes startværdier

type variabel1 = udtryk1,
     variabel2 = udtryk2,
     ...
     variabeln = udtrykn;

Variabel og konstanterklæringer i Java
Slide Note Contents Index
References Speak
I forlængelse af forrige side ser vi videre på variabel og konstant erklæringer i Java

  • Variabelerklæringer

    • Alle navne på variable skal erklæres før brug

    • I forbindelse med en variabelerklæring angives variablens type (statisk og stærk typning), og ofte også variablens initialværdi

    • Der findes ikke nogen speciel variabelerklæringssektion i en procedure. Erklæringer og kommandoer kan blandes frit

  • Konstanterklæringer

    • Konstanter erklæres som 'final static' variable

Program: Et Java program med forskellige erklæringer. I programmet ser vi en erklæring af en 'konstant' PI og en heltals variabel a. Både PI og a er i realiteten at betragte som globale variable. Hvorfor dette er tilfældet vil vi først indse, når vi har studeret statiske klasseegenskaber senere på kurset. I proceduren main erklæres de lokale variable aNumber samt a og b. Dette er lokale variable i proceduren main. Bemærk, at erklæringer kan blandes med kommandoerne (de to println kommandoer) i proceduren; Og bemærk at a er redefineret i main. De sædvanlige scoperegler er gældende, således at indre (mere lokale) definioner overskygger ydre (mere globale) definitioner. Output fra programmet er pi er 3.14159 og videre aNumber = 6.28318 og a = 6
class DeclarationsDemo {

  static final double PI = 3.14159;
  static int a = 2;
  
  public static void main (String[] args) {
    System.out.println("pi er " + PI);
   
    double aNumber = 2 * PI;
    int a = 6, b = 5;
  
    System.out.println("aNumber = " + aNumber +
                       " og a = " + a);
  }

}

Hvad med enumeration types i Java?
Slide Note Contents Index
References Speak
En Pascal programmør gør ofte god brug af de såkaldte enumeration types. Vi opfrisker her hvad dette dækker over, og vi ser på hvordan man begår sig i Java, hvis man skulle have lyst til at lave en enumeration type.

Java understøtter ikke enumeration types ligesom i Pascal.
Som en tilnærmelse kan man bruge konstanter (static final int).

Program: Et Pascal program der illustrerer brugen af enumeration types. Programmet - som har været benyttet på datalogikurset på basisuddannelsen - konverterer fra 13 skala karakterer til bestået ikke bestået.
Program karakterProg;
uses Crt;
Type simpel_karakter = (bestaaet, ikke_bestaaet);
     tal_karakter = (nul_nul, nul_tre, fem, seks, syv, otte,
                     ni, ti, elleve, tretten);

function omsaet_karakter(k: tal_karakter): simpel_karakter;
begin
  if k <= fem
  then omsaet_karakter := ikke_bestaaet
  else omsaet_karakter := bestaaet
end;

procedure print_karakter(k: simpel_karakter);
begin
  case k of
   bestaaet: writeln('bestaaet');
   ikke_bestaaet: writeln('ikke_bestaaet')
  end
end;

begin
  ClrScr;
  print_karakter(omsaet_karakter(syv));
  print_karakter(omsaet_karakter(fem));
  ReadKey
end.

Program: Et tilsvarende Java program. Vi ser for det første, at vi ikke definerer nye typer i Java. Den eneste måde vi kan lave typer på i Java er gennem klassedefinitioner. Det vil kunne lade sig gøre at definere en Karakter klasse hvorpå der laves en ordning, men det vil nok i simple tilfælde være et 'overkill'. Vi laver en mængde af konstanter, hvis værdier er naturlige tal. I bund og grund er enumeration konstanterne blot symbolske navne for udvalgte heltal. Den naturlige ordning på tallene giver en ordning på karaktererne. I Pascal programmet kan man checke grænser automatisk. Dette kan ikke lade sig gøre i Java programmet, idet alle operationer arbejder på typen int, og ikke simpel_karakter eller tal_karakter. Det betyder i praksis at vi burde checke eksplicit i de to procedurer om parametrene giver mening. (Dette har vi ikke gjort her, fordi vi er lidt dovne, og fordi vi ønsker at holde programmerne så sammenlignelige som muligt overfladisk set).
class KarakterProgram {

  static final int BESTAAET = 0;
  static final int IKKE_BESTAAET = 1;

  static final int NUL_NUL = 0;
  static final int NUL_TRE = 3;
  static final int FEM = 5;
  static final int SEKS = 6;
  static final int SYV = 7;
  static final int OTTE = 8;
  static final int NI = 9;
  static final int TI= 10;
  static final int ELLEVE = 11;
  static final int TRETTEN = 13;

  static int omsaet_karakter(int k){
    if (k <= FEM)
       return(IKKE_BESTAAET);
    else return(BESTAAET);
  }
  
  static void print_karakter(int k){
    switch (k){
     case BESTAAET: System.out.println("bestaaet"); break;
     case IKKE_BESTAAET: System.out.println("ikke_bestaaet"); break;
     default: throw new RuntimeException("Ikke eksisterende karakter");
    }
  }
  
  static void main(String[] args){
    print_karakter(omsaet_karakter(SYV));
    print_karakter(omsaet_karakter(FEM));
  }
}



Leksikalske regler i Java

Leksikalske regler
Slide Note Contents Index
References Speak
Tillægsordet 'leksikalsk' benyttes til at tale om egenskaber, som vedrører enkelte ord (i modsætning til egenskaber ved sætningsopbygning mv.) I vores sammenhæng benyttes betegnelsen til at studere regler og begrænsninger for, hvordan ord i Java kan sammensættes af tegn fra Unicode alfabetet (tegnsættet).

  • Et navn i Java skal bestå af tegn, der klassificeres som bogstaver, cifre, understregningstegnet ('_'), eller dollartegnet ('$').

  • Et navn må dog ikke starte med et ciffer

  • Der er forskel på store og små bogstaver i Java navne.

  • Der er ingen grænser for længden af et navn.

  • Alle nøgleord i Java staves med små bogstaver.

Disse regler betyder bl.a., at vi ikke kan have navne, hvori der indgår specialtegn, såsom bindestreg ('-'), spørgsmålstegn eller udråbstegn.

Forskellen på små og store bogstaver i Java navne betyder f.eks. at navnene bankkonto , Bankkonto og BANKKONTO alle er forskellige navne i Java

Langt de fleste moderne programmeringssprog tillader vilkårligt lange navne, og således også Java. Det er som regel vigtigere at vælge et godt og sigende navn for variable, klasse og metoder, end det er at tilstræbe kompakthed via korte navne.

I Java er det muligt at bruge de danske tegn 'æ', 'ø', 'å' samt 'Æ', 'Ø', 'Å' i navne

At danske tegn kan benyttes i Java navne skal tilskrives Java's understøttelse af Unicode alfabetet. Hvis man vælger at 'skrive Java på dansk', er muligheden for anvendelse af danske tegn i navne en meget tilfredsstillende leksikalsk udvikling. I de fleste andre programmeringssprog kan navne kun indeholde tegn fra det basale ASCII alfabet (128 tegn). Man kan også anvende udenlandske specialtegn, f.eks. græske bogstaver, som er populær blandt matematikere. Man vil dog typisk støde på problemer i editorer, som ikke kan vise disse tegn. Endvidere kan det være akavet at indtaste sådanne fremmede tegn via et 'standard tastatur'.

Leksikalske konventioner
Slide Note Contents Index
References Speak
Her vil vi opremse en række nyttige konventioner for dannelse af forskellige slags navne i Java programmerne. Konventionerne er anbefalinger som ikke påtvinges via checks af Java oversætteren.

Vi refererer herunder til en 'Java programmerings standard' af Doug Lea, som går meget videre end vi gør her. Denne kan anbefales som god læsning, hvis man ønsker at skrive konsistente og forudsigelige Java programmer

  • Navne på klasser starter med et stor bogstav

  • Navne på metoder og variable starter med et lille bogstav

  • Navne på konstanter består udelukkende af store bogstaver

  • Vær bevidst om læsbarhed af navne, som er sammensat af flere ord:

    • etMegetLangtNavn

    • et_meget_langt_navn

  • Vær sproglig konsekvent: Formuler enten navne på engelsk eller dansk

Det er et spørgsmål om smag og behag, om man adskiller ord i lange navne med understregningstegnet eller om hvert ord starter med stort. Jeg fortrækker selv sidstnævnte konvention

Det kan være forvirrende at benytte navne, som kun adskiller sig via brug af store og små bogstaver

Som allerede omtalt, er navnene pip , Pip , pIp og, PIP alle forskellige i Java. Anbefalingen er her kun at benytte ét af disse navne i et Java program. På denne måde undgår man unødig forvirring hos programmører, som ikke er 100% bekendt med de leksikalske regler i Java.

Reference


Kommandoer i Java

Kommandoer - generelt og i Java
Slide Note Contents Index
References Speak
I imperative programmeringssprog er kommandoerne af primær betydning. Det er gennem kommandoerne at handlingerne sker. Vi giver her en generel oversigt og klassificering af kommandoer i et imperativt sprog.

  • Assignment

    • Den vigtigste og mest karakteristiske primitive kommando i imperative sprog

Syntax: Variablen på venstre side tilskrives værdien af udtrykket på højre side. Som kommando, skal et assignment altid efterfølges af et semikolon

variabel = udtryk;

I Java har man valgt syntaksen variabel = expression til assignment. Hermed følger Java syntaksen fra sprog i C familien. Dette er ærgerligt idet '=' anvendes som lighedsoperator i Pascal familien af sprog. (I Java anvendes '==' som lighedsoperator). Det er naturligvis meget vigtigt ikke at forveksle assignment kommandoen med lighedsoperatoren.

  • Procedurekald

    • Forskellige mekanismer til overførsel af parametre

  • Kontrolstrukturer

    • Sekventielle, selektive og iterative

I Java er der semikolon efter en kommando

I Pascal bruges semikolon mellem kommandoer

Den tomme kommando
Slide Note Contents Index
References Speak
For god ordens skyld bør vi ikke glemme den mest simple kommando, der findes

Den tomme kommando gør ingenting

På steder, hvor der forventes en kommando, kan vi vælge den tomme kommando. Denne kommando ændrer ikke på programmet's tilstand

Syntax: Det eneste spor af den tomme kommando er det semikolon, som følger efter det

; 

Blokke
Slide Note Contents Index
References Speak
Blokke benyttes til at gruppere et antal kommandoer til én kommando. Blokke kan ligeledes bruges til at introducere erklæringer af variable mv.

The concept blok: En blok er gruppering af kommandoer til én kommando hvori der også kan forekomme variabelerklæringerEn blok er en gruppe af kommandoer som har status af én enkelt kommando. I gruppen af kommandoer kan der forekomme erklæringer af variable.

Syntax: Bestanddelene i en blok omsluttes af tuborg parenteser, herefter kaldet 'klammer'

{kommando-eller-erklærings-liste}

I forhold til Pascal svarer en blok til 'Begin ... End'. I Pascal kan vi ikke erklære nye navne i mellem begin og end. Det kan man derimod altid i Java blokke. Vi vil se mange eksempler på brug af blokke i det efterfølgende

Program: Et Java eksempelprogram med forskellige blokke. Vi ser her, at kroppen af procedurer blot er blokke.
class BlockDemo1 {

static int var1;

static void proc(int p){ 
  var1 = p;
}

public static void main(String[] args){  
  
  int var2;

  var1 = 5;

  {   
    var1 = 6;
    int var3 = 7;  //erklæring i blok
    var2 = 8;
    var3 = 9;
  }

  
  if (var1 == 5)
    var1 = 6;

  if (var1 == 6){    
    var1 = 7;
    proc(8);
    var2 =10;
  }
 }//main

}


Program: Samme eksempel som ovenfor med markering af andre blokke. I main 'hovedprogrammet' ser vi et antal blokke
/user/normark/courses/prog1/prog1-01/sources/java/noteEksempler/BlockDemo1.java

Kommandoer til udvælgelse i Java (1)
Slide Note Contents Index
References Speak
Ligesom i Pascal findes der både en 'if' og en 'case'. Syntaksen er dog lidt anderledes end i Pascal.

Syntax: Den betingede kommando består af et logisk udtryk (boolsk udtryk), som altid skal være i parenteser. Derefter kommer kommandoen. Bemærk, at der ikke er et 'then' nøgleord

if (logiskUdtryk)
  kommando

Syntax: Den selektive if-else kommando er syntaktisk en betinget kommando med en efterfølgende 'else clause'

if (logiskUdtryk)
  kommando1
else
  kommando2

Semantisk er der ingen overraskelser i Java's if og if-else kontrolstrukturer. Syntaktisk skal man bemærke, at der altid skal være parenteser om det logiske udtryk, som bruges til at vælge den mellem 'grenene'. Endvidere falder det således ud, at der skal være semikolon før else. Dette er anderledes end i Pascal. Årsagen til denne forskel er Java's regel om at semikolon bruges efter kommandoer, og ikke imellem kommandoer

Program: En if-then-else kæde i et Java programfragment. Eksemplet viser hvorledes if-else kommandoer i Java kan indlejres i hinanden for at danne en såkaldt if-then-else kæde. Eksemplet som så er interessant idet det afspejler den 'officielle' afbildning af procentpoint til karakterer ved skriftlige eksamener i naturvidenskab og teknik.
int procent, karakter;

  System.out.print("Hvormange procent? ");
  procent = Keyboard.readInt();

  if (procent >= 90)
    karakter = 11;
  else if (procent >= 82)
    karakter = 10;
  else if (procent >= 74)
    karakter = 9;
  else if (procent >= 66)
    karakter = 8;
  else if (procent >= 58)
    karakter = 7;
  else if (procent >= 50)
    karakter = 6;
  else if (procent >= 40)
    karakter = 5;
  else if (procent >= 0)
    karakter = 3;
  else karakter = 0;

Kommandoer til udvælgelse i Java (2)
Slide Note Contents Index
References Speak

Syntax: Switch kommandoen er en selektiv kommando, der udvælger en kommando-liste til udførelse baseret på værdien af udtryk . Typen af udtrykket skal være heltallig eller char

switch (udtryk) {
  case værdi1: kommando-liste1
  case værdi2: kommando-liste2
  ...
  default: kommando-liste3
}

Program: Et program der demonstrerer switch i Java. Programmet udskriver et månedsnavn på basis af en heltals variabel month, som indeholder nummeret på måneden. Bemærk udførelsen af break i hvert 'case'. Uden disse breaks vil det matchende tilfælde samt alle de efterfølgende bliver udført!
class SwitchDemo1 {

public static void main(String[] args){
  int month;
  
  month = 3;
  
  switch (month) {
  case 1:  System.out.println("January"); break;
  case 2:  System.out.println("February"); break;
  case 3:  System.out.println("March"); break;
  case 4:  System.out.println("April"); break;
  case 5:  System.out.println("May"); break;
  case 6:  System.out.println("June"); break;
  case 7:  System.out.println("July"); break;
  case 8:  System.out.println("August"); break;
  case 9:  System.out.println("September"); break;
  case 10: System.out.println("October"); break;
  case 11: System.out.println("November"); break;
  case 12: System.out.println("December"); break;
  }
 }
}

  

Program: Switch uden breaks. Til sammenligning linker vi her til en version af ovenstående program, hvor break kommandoerne er slettet. Prøvekør dette program, og bliv bekræftet i, hvor vigtig break kommandoerne er for switch
/user/normark/courses/prog1/prog1-01/sources/java/noteEksempler/SwitchDemo2.java

Exercise 3.2. Omformning af if til switchSe på og prøvekør programmet, som omregner procentpoint til karakterer ved skriftlige opgaver. Et komplet Java program er til jeres rådighed:

import cs1.Keyboard;

class IfDemo1 {

public static void main(String[] args){
  
  int procent, karakter;

  System.out.print("Hvormange procent? ");
  procent = Keyboard.readInt();

  if (procent >= 90)
    karakter = 11;
  else if (procent >= 82)
    karakter = 10;
  else if (procent >= 74)
    karakter = 9;
  else if (procent >= 66)
    karakter = 8;
  else if (procent >= 58)
    karakter = 7;
  else if (procent >= 50)
    karakter = 6;
  else if (procent >= 40)
    karakter = 5;
  else if (procent >= 0)
    karakter = 3;
  else karakter = 0; 

  System.out.println(procent + "% svarer til karakteren " + karakter);
  }
}

Vær sikker på, at I forstår det i detaljen. Ville programmet virke, hvis vi foretog testene i omvendt rækkefølge?

Det er åbentbart umuligt at få 13 igennem dette program; Kan man få 0 ved brug af dette program?

Diskuter hvorvidt dette program kan omskrives til brug af Java's switch kontrolstruktur. Begrund jeres svar. Udfør gerne en praktisk øvelse med dette, hvor I afprøver jeres evt. løsning i Java.

Dette program kræver adgang til klassen Keyboard eller tilsvarende (SimpletInput, jf. s 111 i Barnes). Hvis ikke din installation giver dig direkte adgang til denne klasse, ligesom det gøres på cs nettet på Aalborg Universitet, kan du blot placere Keyboard klassen i samme katalog som klassen IfDemo1.

Reference

Kommandoer til gentagelse i Java (1)
Slide Note Contents Index
References Speak
Ligesom Pascal har Java tre kontrolstrukturer til gentagelser. Endvidere forholder det sig således, at der er lighedspunkter mellem disse og hhv. while, for og repeat fra Pascal. Dog vil vi se, at der også er forskelle.

Syntax: Kommandoen gentages nul, en eller flere gange sålænge det logiske udtryk er sand

while (logiskUdtryk)
  kommando

Denne kontrolstruktur er helt ækvivalent til while i Pascal. Bemærk dog, at det logiske udtryk skal i parentes og at der ikke er noget 'do' nøgleord.

Program: Et Java program som implementerer Euclids GCD algoritme. Vi ser et program til beregning af største fælles divisor efter Euclid's metode. Til sammenligning linker vi nedenfor til et velkendt Pascal program, som løser samme problem
import oopcourse.util.Console;

class Gcd1{

 static int gcd(int input1, int input2){
   int stor, lille, rest;
   stor = input1;  lille = input2;
   while (lille > 0){
     rest = stor % lille;
     stor = lille;
     lille = rest;
   }
   return stor;
 }

 public static void main(String args[]){
   int i, j;
   i = Console.readInt("Indlæst det største af to positive tal");
   j = Console.readInt("Indlæst det mindst af to positive tal");
   System.out.println("GCD = " + gcd(i,j));
 }
}

Program: Et sammenligneligt Pascal program. Programmet beregner ligeledes den største fælles divisor af to tal.
/user/normark/courses/prog1/prog1-01/sources/noter/includes/gcd.pas

Kommandoer til gentagelse i Java (2)
Slide Note Contents Index
References Speak
I forlængelse af forrige slide ser vi nu på en anden af Java's gentagelsekommandoer, nemlig do.

Syntax: Kommandoen gentages en eller flere gange, sålængde det logiske udtryk er sand

do
  kommando
while (logiskUdtryk)

Denne løkke ligner Pascal's repeat, dog med den undtagelse at det logiske udtryk i Java's do er en 'løkke fortsættelsesbetingelse', hvorimod betingelsen i Pascal's repeat er en 'løkke hop-ud' betingelse. Hvis der skal gentages mere en kommando i en Java do, skal disse kommandoer puttes i en blok

Program: Et program som illustrerer Java's do løkke. Programmet, som bør være velkendt fra basisuddannelsens datalogiundervisning, stiller et spørgsmål indtil der enten svares ja (en streng der starter med tegnet 'j') eller nej (en streng der starter med tegnet 'n').
import oopcourse.util.Console;

class AskUser{

 public static void main(String args[]){
   boolean x;
   String svarString;   char svar;
   boolean positivtSvar;

   do { svarString = Console.readString("Kan du forstå denne do løkke? ");
        svar = svarString.charAt(0);
   } while (svar != 'j' && svar != 'n');
   positivtSvar = svar == 'j';

   System.out.println("Svaret var " + (positivtSvar ? "ja" : "nej"));
 }
}

Program: Et sammenligneligt Pascal program. Også dette program stiller gentagende et spørgsmål indtil der enten svares 'j' eller 'n'.
/user/normark/courses/prog1/prog1-01/sources/noter/includes/ask-user.pas

Kommandoer til gentagelse i Java (3)
Slide Note Contents Index
References Speak

Syntax: I denne løkke udføres init kommandoen først. Hvis det logiske udtryk er sand udføres gentagenKommando. Mellem gentagelserne udføres step kommandoen

for(initKommando; logiskUdtryk; stepKommando)
  gentagenKommando

Java's for løkke bruges i samme situationer, hvor ville bruge Pascal's for løkke. Dette er i situationer, hvor vi på forhånd ved hvormange gange løkkens krop skal gentages. Java's for løkke er dog mere generel end for løkken i Pascal, idet
    init kommandoen kan indeholde en sekvens af flere assignments afslutningen af løkken afgøres af et logisk udtryk, ikke blot en øvre værdi step kommandoen er givet eksplicit; det er ikke bundet fast til et inkrement på én
På grund af disse karakteristika ser vi, at Java for løkken kan bruges i situationer, hvor vi ikke på forhånd kender antallet af løkke gennemløb. Om man gør dette, er et spørgsmål om stil. Jeg anbefaler at vi reserverer for-løkken til situationer, hvor antallet af gennemløb er kendt ved løkken's start.

  • Trin i udførelse af for i Java:

    • Først udføres initialiserings kommandoen

    • Det logiske udtryk beregnes

    • Hvis udtrykket er sandt, udføres gentagenKommando

    • stepKommando udføres

    • Det logiske udtryk beregnes igen

    • ...

Kommandoer til gentagelse i Java (4)
Slide Note Contents Index
References Speak

Pascal

Java

for i := 1 to n do
v := v + i

for(i=1; i<=n; i=i+1)
v = v + i

Program: GCD programmeret med for løkke i Java. Dette eksempel viser viser styrken af Java's for til at styre to variable i en løkke, hvor vi ikke på forhånd ved, hvormange gentagelser der er brug for. Bemærk iøvrigt, at kroppen af for løkken er tom; vi kan tage vare på alle forhold i løkken ved blot at have passende init og step kommandoer.
import oopcourse.util.Console;

class Gcd2{

 static int gcd(int input1, int input2){
   int stor, lille, rest;
   stor = input1;  lille = input2;
   for(stor=input1, lille = input2;
       lille > 0;
       rest = stor % lille, stor = lille, lille = rest);
   return stor;
 }

 public static void main(String args[]){
   int i, j;
   i = Console.readInt("Indlæst det største af to positive tal");
   j = Console.readInt("Indlæst det mindst af to positive tal");
   System.out.println("GCD = " + gcd(i,j));
 }
}

I alle tre slags Java løkker udtrykker betingelserne 'løkke fortsættelsesbetingelser'

Oversigt over Java's hop kommandoer
Slide Note Contents Index
References Speak

Ligesom de fleste andre moderne sprog understøtter Java ikke den generelle 'goto' kommando

Java indeholder dog en rækker 'goto-agtige' kommandoer

  • break - i vilkårlige kontrolstrukturer

    • break;
      Afbryd udførelsen af den nuværende kontrolstruktur og fortsæt udførelsen efter denne

    • break label;
      Afbryd udførelsen af den navngivne kontrolstruktur og fortsæt udførelsen efter denne

  • continue - kun i løkker

    • continue;
      Afbryd en gentagelse i den aktuelle løkke og fortsæt med løkken's næste test

    • continue label;
      Afbryd en gentagelse i den navngivne løkke og fortsæt med denne løkkes næste test

  • return - kun fra metoder

    • return;
      Afbryd udførelsen af den aktuelle metode og returner til metoden's kaldsted (som skal være en kommando)

    • return expression;
      Afbryd udførelsen af den aktuelle metode og returner værdien af expression til metodens kaldsted (som skal være et udtryk)

Program: Eksempler på brug af continue og break. Vi ser to løkker inden i hinanden, hvor variablene i og j gennemløber intervallerne hhv. 1..10 og 1..12. Hvis enten i eller j er lige fortsættes de respektive løkker. Hvis j er lig med 5, afbrydes den inderste løkke. Bemærk de labels 'loop1' og 'loop2' i programmet
class HopDemo1 {

static boolean even(int i){
  return (i % 2 == 0);
}

public static void main(String[] args){
  int i, j;

  loop1: for (i=1; i <=10; i=i+1)
    loop2: for(j=1; j <= 12; j=j+1){
      if (even(i)) continue loop1;
      if (even(j)) continue loop2;
      if (j == 7) break loop2;
     
      System.out.println("(" + i + "," + j + ")");
    }
  }  
}

Exercise 3.3. Break og continueSe på programmet på den tilknyttede slide.Programmet er også her:

class HopDemo1 {

static boolean even(int i){
  return (i % 2 == 0);
}

public static void main(String[] args){
  int i, j;

  loop1: for (i=1; i <=10; i=i+1)
    loop2: for(j=1; j <= 12; j=j+1){
      if (even(i)) continue loop1;
      if (even(j)) continue loop2;
      if (j == 7) break loop2;
     
      System.out.println("(" + i + "," + j + ")");
    }
  }  
}

Find ud af hvad programmet udskriver (i det mindste de første 6 talpar, eller indtil du finder et 'mønster').

Kør dernæst programmet. Er der overensstemmelse mellem dit resultat af ovenstående og programmets faktiske output?

Variér iøvrigt gerne på break og continue kommandoerne på forskellig vis. Vær sikker på, at du kan forklare resultaterne af dine forskellige testkørsler.

Brug kun break og continue i situationer, hvor alternative programformuleringer er for komplicerede


Procedurer og parametre i Java

Oversigt over procedurer og funktioner i Java
Slide Note Contents Index
References Speak
På denne side vil vi pege på nogle få, overordnede fakta om procedurer og funktioner i Java.

  • Procedurebegrebet og funktionsbegrebet i Java

    • Enhver procedure og funktion er en metode i en klasse

    • Forskellen på procedurer og funktioner i Java udgøres af returtypen

      • void: procedure

      • en primitiv datatype eller en klasse: funktion

    • Procedurer kan ikke indlejres i Java

      • Altså ingen lokale procedurer

    • Returnering fra en procedure kan ske implicit eller eksplicit

      • Implicit: Når sidste kommando er udført (kun fra procedurer).

      • Eksplicit: Ved brug af return kommandoen.

Java tilbyder ikke lokalt definerede procedurer i procedurer. Men som vi vil se senere i kurset kan man indlejre klasser i klasser på forskellig måde. Og da procedurer (metoder) er den del af en klasse får vi alligevel muligheden for lokal definition af procedurer og funktioner.

Procedurer og parametermekanismer i Java
Slide Note Contents Index
References Speak
Alle aspekter af et Java program tilhører en klasse. Der er altså ingen program aspekter uden for klasser i Java. Vi vil her interessere os for de generelle procedure egenskaber ved metoderne i Java. Vi vil først i en senere lektion vende tilbage til disse som metoder i klasserne. Vi vil derfor ikke her omtale egenskaber af metoder, som er knyttet til objekt-orienteret programmering.

Syntax: En procedure kendes på, at den angives som void. Efter procedure navnet kommer den formelle parameterliste. Selv i tilfælde af, at der ingen parametre er, skal parenteserne være med. Vi har tidligere omtalt blok-begrebet (klammer med erklæringer og kommandoer)

void procedureNavn(formelParameter-liste)
  blok

At en procedure angives som værende 'void' skal forstås i den sproglige C tradition, hvor procedure opfattes som funktioner, der ikke returnerer nogen værdi.

Syntax: En formel parameterliste indeholder en liste af komma-separerede definitioner af formelle parametre. I hver parameter definition kommer typen før navnet på den formelle parameter.

Type parameterNavn, Type parameterNavn, ...

Den formelle parameterliste i et Java program er mere enkelt opbygget end i Pascal, idet vi ikke kan have grupper af parametre ala integer og real grupper i
    procedure p(a,b,c: integer; d,e: real)
I Java bliver vi nødt til at skrive
    void p(int a, int b, int c, float d, float e)
Læg også mærke til, at typenavnet kommer før parameternavnet. Dette er igen C traditionen som slår igennem

To eller flere procedurer kan have samme navn hvis rækkefølgen og typerne af de formelle parametre er forskellige

Dette kaldes for overloadning. En overloadet procedure identificeres ved signaturen, og ikke blot ved procedurens navn. Signaturen af en procedure udgøres af procedurens navn og typerne af alle formelle parametre, herunder deres rækkefølge. Proceduren p, nævnt ovenfor, har Java signaturen p(int,int,int,float,float). Overloadede procedurer er ofte særdeles praktiske. Disse befrier os nemlig for at opfinde nye navne til procedurer, som blot adskiller sig via typerne og rækkefølgen af deres parametre

Parametermekanismer i Java
Slide Note Contents Index
References Speak
Parametermekanismer er en helt naturlig fortsættelse af historien om procedurebegrebet i Java

Alle parametre i Java overføres som værdiparametre

Variableparametre understøttes ikke af Java

Java er, overfladisk set, enkel hvad angår parametermekanismer. Alle parametre er værdiparametre. Vi bliver dog nødt til at nuancere synet på dette en smule. Mere konkret bliver vi nødt til at skelne mellem hvad det vil sige at parameteroverføre værdier af primitive typer, og objekter af klasse typer

The concept værdiparameter: En aktuel værdiparameter kopieres, og kopien bindes til det formelle parameternavn. Den aktuelle parameter kan ikke ændres ved assignment til den formelle parameterVi definerer her værdiparameter begrebet. Dette parameteroverførselsbegreb involverer kopieringen samt den deraf følgende beskyttelse af den aktuelle parameter

  • Parameteroverførsel af objekter (instanser af klasser):

    • Objekter tilgås altid via en reference

    • Referencen overføres som en værdiparameter

      • Referencen kopieres

      • Objektet kopieres ikke

    • Via en formel parameter kan vi derfor ændre på et parameteroverført objekt

    • Vi kan derimod ikke ændre på referencen til objektet via den formelle parameter

Værdier af primitive typer overføres som værdiparametre.

Objekter af klassetyper overføres som referenceparametre.

Dette udsagn er nok mere reelt end det første og øverste udsagn: 'Konsekvent anvendelse af værdiparametre'. Når vi taler om 'reference parametre', 'pass by reference' eller 'call by reference' er det dog vigtigt at understrege, at der ikke er tale om variabelparametre ala Pascal's. Vi hentyder derimod til overførsel af objekternes referencer som værdiparametre, i den forstand vi diskuterede ovenfor.

Det er ikke muligt at overføre procedurer som parametre i Java. Men da procedurer er en del af et objekter, kan vi let omgå denne tilsyneladende begrænsning. Dette er en lidt mere avanceret observation. Som nogle nok er klar over, kan vi overføre procedurer som parametre i Pascal, og i mange andre sprog. I Java kan vi ikke direkte overføre en procedure P som parametre til procedurer, men vi kan overfører et objekt O, hvori P er en metode. Dette er næsten lige så godt, og i nogle situationer endog bedre, fordi P medbringer 'en kontekst', nemlig objektet og det's tilstand. Notationsmæssigt er det dog tungt og ofte akavet at skulle indlejre en procedure i en klasse, for at kunne overføre den som parameter.


Udtryk og operatorer i Java

Udtryk og operatorer i Java
Slide Note Contents Index
References Speak
Vi går nu nu over til at studere udtryk og operator, som de optræder i Java. Som vi vil se, er der langt flere operatorer i Java end i Pascal. Der er desværre også optræk til en betydelig forvirring, hvor udtryk og kommandoer blandes sammen på en uheldig måde. Vi vil forsøge at bringe orden i denne forvirring inden den får alvorlige konsekvenser for os.

The concept udtryk: Et udtryk er et program fragment, der alene beregnes med henblik på produktion af en værdi.

Beregning af et udtryk kan ikke føre til tilstandsforandringer af variable mv.

Et udtryk kan beregnes, og det returnere altid en værdi. Dette er den rene definition af begrebet. I Java er udtryk dog et mere udflydende begreb. Som vi vil se, er der mange 'udtryk' i Java, som også ændrer tilstanden i programmets lager.

  • Forskellige slags udtryk/operatorer i Java

    • Aritmetiske

      • Operator input og output er af numeriske typer

      • +  -  *  /  %

    • Sammenlignende

      • Output er boolsk.

      • ==  !=  <  <=  >  >= 

    • Logiske

      • Både input og output er boolsk

      • !  &  &&  |  ||  ^

    • Increment/decrement

      • Optællende/nedtællende assignment. Uvæsentlige.

      • ++  --

    • Assignment

      • Assignment er en operator i Java

      • Værdien af et assignment 'v = udtryk' er udtryk's værdi

      • =

    • Akkumulerende assignment

      • Assignment hvor samme variabel forekommer på begge sider af assignment symbolet. Uvæsentlige.

      • +=  -=  *=  /=  %=  <<=  
        >>=  >>>=  &=  ^=  |=

    • Bitvise

      • Lavniveau operatorer, der arbejder på bitrepræsentation af data

      • ~  <<  >>  >>>  &  ^  |  

    • Betinget

      • Speciel, tertiær operator. If-then-else for udtryk.

      • ?:

Reference
  • Oversigt over Java operatorer: Lewis and Loftus (2ed), appendix D, side 549
    The reference above goes to paper material

En del operatorer er overloadede, således at deres betydning af hænger af typen af parametrene

Operator prioriteter
Slide Note Contents Index
References Speak
Ligesom i Pascal har operatorer prioriteter i Java. Og principperne bag prioriteringen er nøjagtig den samme. Dog har Java 15 prioriteringsklasser mod Pascal's fire, fem stykker

Operator prioriteter benyttes til at fastlægge beregningsrækkefølgen af deludtryk i et sammensat udtryk

Deludtryk med højt-prioriterede operatorer udregnes før deludtryk med lavere prioriterede operatorer

En højt prioriteret operator har en lavt prioritetstal i tabellen nedenfor

Table. Operator prioriteter for operatorerne omtalt ovenfor. De højst prioriterede operatorer står øverst i tabellen.

Vi lægger mærke til at de sammenlignende operatorer (< og > eksempelvis) er højere prioriterede end logisk and og or. Det betyder at udtrykket

    x < y && y < z
giver mening uden parenteser. Dette er en kontrast til Pascal hvor vi bliver nødt til at sætte parenteser
    (x < y) and (y < z)
idet and operatoren er højere priorieteret end 'mindre end' operatoren.

Bemærk dog, at man i Java gerne må sætte de parenteser man har lyst til for at understrege den syntaktiske sammenhæng i et udtryk.

PrioritetOperatorer
1Array indicering []
Dot operator
Postfix increment/decrement
2Prefix increment/decrement
Unær + og -
Not
3new operator
Type casts
4Multiplikative aritmetiske operatorer
5Additive aritmetiske operatorer
6Bitvise shift operatorer
7Mindre og større end
instanceof
8Lighed og forskellig fra
9Logisk og bitvis and
10Logisk og bitvis or
11Logisk short circuit and
12Logisk short circuit or
14Den betingede operator
15Assignment operatorer
 

Increment, decrement og assignment operatorer i Java
Slide Note Contents Index
References Speak
Java indeholder en række operatorer, samt en række afarter af assignments, som tilhører en af C-kulturens mørke sider. Årsagen er, at begreberne udtryk og kommandoer sammenblandes på en meget uheldig måde. Vi nævner her kort de forskellige muligheder i Java, men vi vil klart anbefale at man ikke gør brug af dem!

The concept postfix operator: En postfix operator såsom v++ tæller en variabel op efter værdien returneresPre- og postfix operatorer er både udtryk og kommandoer. Dvs. at en sådan konstruktion kan forekomme både de steder vi forventer en kommando, og de steder, hvor kun udtryk giver mening. Forvirringen opstår primært når vi anvender pre- og postfix operatorer som udtryk. Her er det nemlig væsentligt, om optællingen sker før eller efter vi returnerer (og anvender) værdien. Når disse konstruktioner anvendes som rene kommandoer, er det ligegyldigt, om vi benytter prefix eller postfix formen. Vær dog så venlig at skrive 'v = v+1' eller 'v = v-1' i stedet for!
The concept prefix operator: En prefix operator såsom ++v tæller en variabel op før værdien returneres

Lad op være en binær operator.

En assignment operator udtrykker assignmentet

     x = x op y

som

     x op= y
En assignment operator erstatter et almindeligt 'akkumulerende' assignment (et assignment, hvor samme variable forekommer på begge sider af assignment symbolet) med en alternativ og kortere udtryksform. I nogle implementationer kan den alternative udtryksform også være mere effektiv.

Overdreven anvendelse af pre- og postfix operatorer samt assignments i udtryk giver ofte uigennemskuelige programmer

Den betingede operator i Java
Slide Note Contents Index
References Speak
En if-then-else konstruktion (if e then s1 else s2) opfattes som regel som en kommando (og en kontrolstruktur). I mange programmeringssprog kan man også bruge if-then-else i udtryk. Vi siger undertiden, at if-then-else anvendt i udtryk er en betinget operator. Eksempelvis er
    2 + if even(a) then a else a + 1
et fuldgyldigt udtryk i sådanne sprog. Java understøtter dette, men i en anden syntaks

Syntax: Det logiske udtryk beregnes først. Hvis værdien er sand, beregnes og returneres udtryk1, ellers beregnes og returneres udtryk2

logiskUdtryk ? udtryk1 : udtryk2

Program: Her ser vi den velkendte fakultetsfunktion, hvor kroppen essentielt er ét udtryk programmeret med den betingede operator
static int fak(int n){
   return 
     n == 0 ? 1 : n * fak(n-1);
 }

Program: Til sammenligning ser vi en anden version af fakultetsfunktionen, hvor kroppen indeholder en if then else kontrolstruktur
static int fak1(int n){
   if (n == 0)
     return 1;
   else return n * fak1(n-1);
 }


Input output og programstrukturering

Output i Java
Slide Note Contents Index
References Speak
For at forstå Java's input/output faciliteter skal man forstå de basale, objekt-orienterede udtryksformer i sproget. Årsagen er, at Java håndterer input og output via operationer på objekter. Vi vil her se på nogle simple, 'idiomatiske' teknikker til besørgelse af input og output. Den fulde forståelse af disse vil først indfinde sig, når vi har studeret objekt-orienteret programmering lidt nærmere i Java.

Output besørges ved at kalde print eller printlnout i System klassen

Og hvordan skal dette egentlig forstås? Forklaringen er, at at out er en statisk variabel (klasse variabel) i klassen System. Out refererer et objekt af typen PrintStream, som understøtter et helt arsenal af forskellige print og println metoder. Dette er sikkert svært at forstå på nuværende tidspunkt i kurset. Så foreløbigt kan man blot slå sig til tåls med, at man skriver System.out.print(...) når man vil skrive ud på skærmen.

Program: Eksempler på anvendelse af print og println kommandoer. + operationerne sætter strenge samme til en ny streng. Anvendt på denne måde er der altså ikke tale om aritmetisk addition. Værdierne af variablene i, d, b og c vil alle blive konverteret til tekststrenge når de anvendes i en streng sammensætnings sammenhæng.
class IoDemo1 {

public static void main(String[] args){

  int i = 1; double d = 1.1 ; boolean b = true ; char c = 'a'; 

  System.out.println("En streng");
  System.out.print("i = " + i + ". ");
  System.out.print("d = " + d + ". ");
  System.out.print("b = " + b + ". ");
  System.out.print("c = " + c + ". "); 
  }

}

Reference

Input i Java
Slide Note Contents Index
References Speak

Input er desværre mere kompleks via klasserne i JDK bibliotekerne

  • Indlæsning af tal og andre simple værdier er unødig indviklet i Java

  • De fleste lærerbøger har udviklet egne klasser til at råde bod på dette problem

    • Core Java: Klassen Console

    • Lewis and Loftus: Klassen Keyboard

    • Barnes: Klassen SimpleInput

References

Program: Eksempler på anvendelse af input kommandoer fra klassen Console.
import oopcourse.util.Console;

class IoDemo2 {

public static void main(String[] args){

  System.out.println("Console Demo");

  int i; double d ; String s;

  i = Console.readInt("Indlæs et heltal: ");
  d = Console.readDouble("Indlæs et reelt tal: ");
  s = Console.readString("Indlæs en tekststreng: "); 

  System.out.print("i = " + i + ". ");
  System.out.print("d = " + d + ". ");
  System.out.print("s = " + s + ". ");

  }

}

Program: Eksempler på anvendelse af input kommandoer fra klassen Keyboard.
import cs1.Keyboard;

class IoDemo3 {

public static void main(String[] args){
  
  System.out.println("Keyboard Demo");

  int i; double d ; String s;

  System.out.print("Indlæs et heltal: ");
  i = Keyboard.readInt();

  System.out.print("Indlæs et reelt tal: ");
  d = Keyboard.readDouble();

  System.out.print("Indlæs en tekststreng: ");
  s = Keyboard.readString(); 

  System.out.print("i = " + i + ". ");
  System.out.print("d = " + d + ". ");
  System.out.print("s = " + s + ". ");

  }

}

Program: Eksempler på anvendelse af input kommandoer fra klassen SimpleInput.
// import oopcourse.util.SimpleInput;  
// Kræver pt. at SimpleInput.class findes i samme katalog som IoDemo4.class

class IoDemo4 {

public static void main(String[] args){
  
  System.out.println("SimpleInput Demo");

  SimpleInput keyboard = new SimpleInput();

  int i; double d ; String s;

  System.out.print("Indlæs et heltal: ");
  i = keyboard.nextInt();

  System.out.print("Indlæs et reelt tal: ");
  d = keyboard.nextDouble();

  System.out.print("Indlæs en tekststreng: ");
  s = keyboard.nextLine(); 

  System.out.print("i = " + i + ". ");
  System.out.print("d = " + d + ". ");
  System.out.print("s = " + s + ". ");

  }

}

Exercise 3.4. Indlæsning af heltalSom det fremgår af lærebogen er indlæsning af tal et noget mere kompliceret problem end blot indlæsning af en tekstlinie. For at indlæse et heltal skal man udtrække cifrene af den indtastede tekststreng (en form for parsning) og beregne tallet. Hvis man synes, at dette er for omstændeligt, kan man bruge et alternativt bibliotek, som indholder en mere direkte 'readInt' metode, f.eks. via klassen Console i kataloget /pack/local-java/lib/corejava/ eller klassen Keyboard fra Lewis og Loftus (2ed).

I denne opgave vil vi, for øvelsens skyld, selv programmere en procedure, som indlæser et heltal fra tastaturet. Dette giver en nyttig indsigt i forskellen mellem at læse tekst og tal. Opgaven går altså ud på at indlæse en række tegn, som danner et heltal, og dernæst konvertere de indlæste tegn til et tal af typen int. Man kan sige, at øvelsen går ud på at programmere operationen parseInt - som Java anvender for at løse opgaven.

Udfyld derfor detaljerne i følgende programskabelon:

/* Læs et tal fra en linie af tegn, og returner det pågældende tegn som en int */

import java.io.*; // for at kunne anvende BufferedReader mv.

class talLaesning {

  //et objekt, kaldet stdin, som tillader os at læse en tekst linie:
  static BufferedReader stdin = new BufferedReader (new InputStreamReader(System.in));

  public static int readInt() throws IOException{
  /* Read an integer from the keyboard, and return it as the result of this function */

     String textLine;
     int tal = 0;
     textLine = stdin.readLine();
  
     // Læs her et tegn fra strengen textLine og konverter tegnet til et tal.
     // Udregn løbende tallet, som hidtil er indlæst, og opbevar det i variablen tal.
     // Det i'te tegn i strengen s læses med s.charAt(i).
     // Iøvrigt er de statiske metoder isDigit og digit i klassen Character
     // sikkert nyttige.

     return tal;
  }

  // hovedprogrammet, som kalder readInt:
  public static void main (String[] ars) throws IOException{
     System.out.println("Indlaes et tal");
     int etTal = readInt();
     System.out.println("Tallet var: " +  etTal);
  }

}
  
Der henvises til klassen Character for funktioner, som aflæser og returnerer egenskaber af et tegn i typen char.

Program skabelonen kan downloades til en fil via følgende link: Skabelon

Kommandoerne til input og output er implementeret som procedurer i biblioteksklasser. Java sproget understøtter ikke direkte input eller output

Reference

Hvordan struktureres et konventionelt program i Java?
Slide Note Contents Index
References Speak

Alle aspekter af et program struktureres i klasser i Java

I Java findes der ingen programdele uden for klasserne. Det er altså ikke muligt at skrive en 'programstump' uden om, eller udenfor rammerne af en eller flere klasser i Java. På denne side vil vi se, hvordan man kan benytte klassebegrebet idiomatisk til alligevel at skrive et normalt, Pascal-agtigt program i Java

  • Hovedprogrammet modsvares af en statisk metode i Java, som skal hedde main

  • Andre procedurer og funktioner kan laves som statiske metoder i klassen

  • Det er ikke muligt for metoder at have lokale metoder i Java

  • Globale variable modsvares af statiske variable i klassen

  • Nye typer i Java laves som abstrakte datatyper, og implementeres som en klasse i Java

  • Klassen C, som indeholder main metoden, skal placeres på en fil navngivet C.java

Program: Et eksempel på et konventionelt program skrevet i Java.
public class AProgramDemo {

  static int enGlobalVariabel;

  static EnNyType enAndenGlobalVariabel = new EnNyType();

  public static void enProcedure(int par){
    System.out.println("Procedurens parameter = " + par);
    enAndenGlobalVariabel.felt1 = 7;
    System.out.println("Felt1 i den anden globale variabel = " + 
                        enAndenGlobalVariabel.felt1);
  }

  public static void main(String[] args){
    enGlobalVariabel = 5;
    enProcedure(enGlobalVariabel);  //kald af procedure
  }
} 


class EnNyType{
  int felt1;
  double felt2;
}

The concept statisk klasse egenskab: En statisk egenskab af en klasse tilhører klassen, og er fælles for alle objekter. Statiske egenskaber kan tilgås uden først at lave instanser af klassen


Dokumentation af Java

Dokumentation af Java
Slide Note Contents Index
References Speak
Vi ser her kort på, hvordan man finder dokumentation af Java

Med det tempo Java har udviklet sig bliver de fleste opslagsbøger om Java forældet alt for hurtigt.

Det anbefales at bruge online opslagsværker hvis man skal have konkret og opdateret information om Java bibliotekerne, Java værktøjer, og Java sproget.

Man kan håbe, at Java efterhånden er så stabil, at den trykte dokumentation vil kunne leve længere.

  • Online beskrivelser af Java:

    • Java Application Programmer's Interface (API)

    • Nogle få lokale java klasser (API)

    • The Java Tutorial

    • The Java Language Specification

    • Java Programming Language Basics, Part 1 og 2

Java API dokumentation følger ikke med når man downloader Java fra Sun's WEB site. Husk derfor at få fat i denne meget vigtige del af Java Systemet, når du hjemtager en ny version af Java Development Kit (JDK).

De lokale java klasser er klasser, som vi anvender en del på kurset, herunder Keyboard og Console.

Også The Java Tutorial er en separate enhed i forhold the JDK systemet. Denne samling af dokumentation opdateres ganske ofte hos Sun med nye dele. Vær også opmærksom på, at dette kan købes i bogform. Pt. er der tre tykke bøger, som er identiske med online materialet.

En Java 1.0 beskrivelse af sproget. Denne meget omfattende sprograpport er desværre ikke opdateret hverken til version 1.1 eller 1.2. Der findes kun et kort appendix, som beskriver sproget's udvikling fra 1.0 til 1.1.

En kortere og mere basal tutorial end 'The Java Tutorial'. Samlingen er opdelt i en række korte kapitler

References

Den mest opdaterede information fås på java.sun.com

Opgaven polygon tegning
Slide Note Contents Index
References Speak

Exercise 3.5. Tegning af en regulær polygonKlassen Crayon er en simpel klasse - set fra et grænseflade synspunkt - som gør det muligt at lave stregtegninger. Studér først klassens grænseflade, og forstå hvilke tjenester den tilbyder.

Benyt nu klassen Crayon til at skrive et program, som tegner en regulær n-kant (ligesidet trekant hvis n er 3, et kvadrat hvis n er 4, en regulær pentagon hvis n er 5, etc). Indlæs n fra tastaturet, f.eks. via klassen Keyboard.

Dit program skal naturligvis have adgang til klassen Crayon. Hvis dit Java system allerede har adgang til klassen, skal du blot importere klassen eller pakken hvori den forekommer. Hvis ikke, kan du placere Crayon klassen i samme katalog som din egen klasse. Det samme gælder for Keyboard. Dette giver umiddelbart adgang til klasserne fra dit eget program.

På cs nettet findes Crayon klassen i pakken oopcourse.util. Klassen Keyboard findes i cs1 pakken - ligesom det antages i lærebogen.


Collected references
Contents Index
Klassen BigInteger
The reference from above goes to Java API pageThe references above goes to material on the Internet
Afsnit 3.10.2 i sprogspecifikationen om literal syntaks for float of double
The references above goes to material on the Internet
Afsnit 3.10.6 i sprogspecifikationen om tegn
The references above goes to material on the Internet
Afsnit 3.3 i sprogspecifikationen om tegn
The references above goes to material on the Internet
Unicode
The references above goes to material on the Internet
Klassen BigInteger i pakken java.math
The reference from above goes to Java API pageThe references above goes to material on the Internet
Wrapper klassen Long i pakken java.lang
The reference from above goes to Java API pageThe references above goes to material on the Internet
Wrapper klassen Integer i pakken java.lang
The reference from above goes to Java API pageThe references above goes to material on the Internet
Wrapper klassen Float i pakken java.lang
The reference from above goes to Java API pageThe references above goes to material on the Internet
Wrapper klassen Double i pakken java.lang
The reference from above goes to Java API pageThe references above goes to material on the Internet
Wrapper klassen Character i pakken java.lang
The reference from above goes to Java API pageThe references above goes to material on the Internet
Wrapper klassen Byte i pakken java.lang
The reference from above goes to Java API pageThe references above goes to material on the Internet
Wrapper klassen Boolean i pakken java.lang
The reference from above goes to Java API pageThe references above goes to material on the Internet
Strenge i Java
The reference above goes to a lecture note pageThe reference above points to an succeding page in the lecture notes
Introduktion til Collections
The reference above goes to a Java Tutorial pageThe references above goes to material on the Internet
Collections i Java
The reference from above goes to Java API pageThe references above goes to material on the Internet
Collections
The reference above goes to a lecture note pageThe reference above points to an succeding page in the lecture notes
Arrays i Java
The reference above goes to a lecture note pageThe reference above points to an succeding page in the lecture notes
Klasser i forhold til records
The reference above goes to a lecture note pageThe reference above points to an earlier page in the lecture notes
Doug Lea's Java Coding Standard
The references above goes to material on the Internet
Om break kommandoen
The reference above goes to a lecture note pageThe reference above points to an succeding page in the lecture notes
Oversigt over Java operatorer: Lewis and Loftus (2ed), appendix D, side 549
The reference above goes to paper material
Variablen out i klassen System
The reference from above goes to Java API pageThe references above goes to material on the Internet
Dokumentation af klassen SimpleInput
The references above goes to material on the Internet
Dokumentation af klassen Console
The references above goes to material on the Internet
Dokumentation af klassen Keyboard
The references above goes to material on the Internet
Stream klasserne i Java
The reference above goes to a lecture note pageThe reference above points to an succeding page in the lecture notes
Java Programming Language Basics, Part 2
The references above goes to material on the Internet
Java Programming Language Basics, Part 1
The references above goes to material on the Internet
Artikler fra Java Developer Connection
The references above goes to material on the Internet
The Java Language Specification
The references above goes to material on the Internet
Java 2 SDK Documentation
The reference from above goes to Java API pageThe references above goes to material on the Internet
Dokumentation af lokale Java klasser
The references above goes to material on the Internet
The Java Tutorial
The reference above goes to a Java Tutorial pageThe references above goes to material on the Internet

 

Chapter 3: De ikke objekt-orienterede dele af Java
Course home     Author home     About producing this web     Previous lecture (top)     Next lecture (top)     Previous lecture (bund)     Next lecture (bund)     
Generated: March 31, 2008, 12:08:12