300 likes | 482 Views
Grundlæggende programmering Efterår 2001. Forelæsning 3 onsdag 12/9 2001 kl. 9:15 – 12:00. Dagens program. Det praktiske Klasser og objekter i Java: klassedeklarationer instansvariable metodedeklarationer. Det praktiske.
E N D
Grundlæggende programmeringEfterår 2001 Forelæsning 3 onsdag 12/9 2001 kl. 9:15 – 12:00
Dagens program • Det praktiske • Klasser og objekter i Java: • klassedeklarationer • instansvariable • metodedeklarationer
Det praktiske • Opgaveaflevering: Husk at aftale med Jeres instruktor, hvordan opgaver skal afleveres. (Hvis ikke andet er aftalt, læg da besvarelserne i dueslaget ”Grundlæggende Programmering” uden for studieadministrationen.)
betingelse true false ordre while-løkker Udførelsesorden: Syntaks: while ( betingelse )ordre • while-løkken kører sålænge betingelse er sand. • Ordren under while hedder løkkekroppen og kan være en blokordre.
Halvering (diskret logaritme) public class Logarithm { // diskret logaritme base 2; // argument skal være positiv public int log2(int n) { int log = 0; while (n > 1) { log++; n /= 2; } return log; }
betingelse true ordre false do-løkker Udførelsesorden: Syntaks: do ordrewhile ( betingelse ) • do-løkken kører sålænge betingelse er sand. • Løkkekroppen udføres mindst 1 gang!
betingelse true false initialisering optælling ordre for-løkker Syntaks: for (initialisering; betingelse; optælling) ordre • initialisering er normalt en initialiseret variabelerklæring (f.eks. int n=0). • Hvis betingelse er udeladt, betyder det ’true’. • optælling er normalt en eller flere tildelinger (f.eks. n++, m++)
betingelse true false ordre betingede ordre (uden else-gren) Syntaks: if ( betingelse ) ordre • betingelse udføresaltid 1 gang. • ordre udføres 0 eller 1 gang.
betingelse true false ordre1 ordre2 betingede ordre (med else-gren) Syntaks: if ( betingelse ) ordre1 else ordre2 • betingelse udføresaltid 1 gang. • kun en af ordrene ordre1 og ordre2 udføres.
block-ordre • Flere ordre kan grupperes til en blokordre. • En blok(ordre) indikeres med krøllede parenteser: { ordre1; ordre2; ...} • En blokordre kan bruges alle steder, hvor en ordre er påkrævet.
Flervejsvalg: Switch-ordre • Switch-ordren har den generelle form switch (heltals-udtryk) { case heltal : ordrer case heltal : ordrer . . . case heltal : ordrer default : ordrer } Hvert sæt af ordrerender som regel med ordren ‘break' eller ‘return‘. Alle ‘case’ tallene skal være forskellige. Udtrykket heltals-udtryk udregnes til et heltal n. Hvis der er en case-gren mærket n, så fortsætter programudførelsen med den gren. Hvis ingen case-gren er mærket n, så fortsætter programudførelsen med default-grenen hvis der er en; ellerssker der ingenting.
13-skala public class Karakter { public static void main(String[] args) { int k = Integer.parseInt(args[0]); System.out.println(karakterTekst(k)); } static String karakterTekst(int karakter) { switch (karakter) { case 13: return "For den usædvanlig selvstændige og udmærkede præstation."; case 11: return "For den udmærkede og selvstændige præstation."; case 10: return "For den udmærkede, men noget rutineprægede præstation."; case 9: return "For den gode præstation, der ligger lidt over middel."; case 8: return "For den middelgode præstation."; case 7: return "For den ret jævne præstation, der ligger lidt un..."; case 6: return "For den netop acceptable præstation."; case 5: return "For den usikre og ikke tilfredsstillende præstation."; case 3: return "For den meget usikre, meget mangelfulde og util..."; case 0: return "For den helt uantagelige præstation."; default: return "Karakter er ikke gyldig."; } } }
Gennemfald • Udeladelse af ordren ‘break’ betyder at programudførelsen ‘falderigennem' til næste sæt ordrer. • Dette bruges når flere tilfælde (`cases') skal udføre samme ordrer. • Ordren ‘break’ kan udelades hvis den sidste ordre i encase grener return. • Ellers skyldes udeladelse af `break’ som regel en forglemmelse -- en hyppig kilde til fejl i C, C++ og Java-programmer!
Typisk brug af gennemfald // Length of the months (non-leap years) public class Days4 { public static void main(String[] args) { int mth = Integer.parseInt(args[0]); System.out.println("Måned " + mth + " har længde " + monthlen(mth)); } static int monthlen(int mth) { switch (mth) { case 1: case 3: case 5: case 7: case 8: case 10: case 12: return 31; case 2: return 28; case 4: case 6: case 9: case 11: return 30; default: return 0; } } }
Månedslængde // Length of the months (non-leap years) public class Days5 { public static void main(String[] args) { int mth = Integer.parseInt(args[0]); int year = Integer.parseInt(args[1]); System.out.println("Måned " + mth + " har længde " + monthlen(mth,year) + " i år " + year); } static int monthlen(int mth, int year) { switch (mth) { case 1: case 3: case 5: case 7: case 8: case 10: case 12: return 31; case 2: if ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)) return 29; else return 28; case 4: case 6: case 9: case 11: return 30; default: return 0; } }}
Pas på med gennemfald static void sw(int n) { switch (n) { case 23: case 3: System.out.println("A"); break; case 32: case -2: case 42: System.out.println("B"); case 12: case 8: System.out.println("C"); break; case 34: System.out.println("D"); default: System.out.println("F"); case 7: System.out.println("G"); } } } // Length of the months (non-leap years) public class Switch { public static void main(String[] args) { sw(42); System.out.println("----"); sw(4); System.out.println("----"); sw(7); System.out.println("----"); sw(12); } Hvad udskriver programmet for sw(42), sw(4), sw(7) og sw(12)?
Klasser og objekter • En klasse repræsenterer et begreb: tidspunkt, aftale, bil, ko, person, terning, tegnemaskine, osv. • Et objekt repræsenterer en bestemt ting, en instans af et begreb: kl. 8:08 i dag, vejledningsmødet med Jakob og Ole i morgen, min VW Passat, Nanna med den lille kalv, Mads Tofte, den røde terning i min udgave af Matador, den tegnemaskine som har lige tegnet den store firekant, osv.
Klasser i Java • Klassen beskriver: • hvilke instansvariable hvert objekt af klassen har (objektets tilstand) • hvilke konstruktorer klassen har, som kan bruges for at skabe objekter fra klassen(“instansiere klassen”) • hvilke metoder hvert objekt af klassen har • plus andre ting, vi ikke beskæftiger os med endnu. • Java har en række indbyggede klasser: String, Random, osv. • Vi bruger en klasse ved at: • lave et nyt objekt ved hjælp af klassens konstruktorer; • invokere en metode på et objekt • tilgå en instansvariable på et objekt • Vi definerer en klasse ved at angive i en klassedefinition: • de instansvariable hvert objekt af klassen vil have • en eller flere konstruktorer for at instansiere og initialisere nye objekter • programkode for de metoder hvert objekt har.
Tid class Time { int hours = 0; int min = 0; } class Time1 { public static void main(String[] args) { Time t1; t1 = new Time(); // Lav et objekt fra klassen Time; tildel objektets navn til t1 t1.hours = 12; // Tildeling til instansvariable i objektet t1.min = 35; Time t2 = new Time(); // Erklæring med initialisering t2.hours = 14; } } Instansvariable Ingen eksplicit konstruktor: Java tilføjer automatisk konstruktor Time(){} Ingen metoder!
Instansvariable • En instansvariable (felt) indeholder på et givet tidspunkt altid en værdi af den type i instansvariablens deklaration. • En værdi kan være af primitive type (int, double, boolean) eller den kan være en objektreference. • En objektreference er et objekts addresse i computerens lager. • Et objekt har altid den samme unikke addresse, forskellig fra alle andre objekters addresser. • En variable indeholder kun addressen på et objekt, ikke selve objektet . • Tildeling var1 = var2 kopierer indeholdet fra var2 og gør det nye indhold af var1. Hvis var2 indeholder en objektreference er kun objektreferencen kopieret, ikke objektet selv!
Konstruktorer • En konstruktor er en speciel metode for at lave et nyt objekt med et nyt navn, allokere plads til det i computerens lager, og returnere en reference til objektet; dvs. addressen, hvor objektet ligger. • En konstruktor: • skal have samme navn som klassen • returner ikke nogen værdi • har ikke nogen returtype, ikke engang void • bruges ofte for at initialisere instansvariablerne i det nye objekt. • Hvis klassen ikke indeholder nogen konstruktor, definerer Java en default konstruktor uden parametre, som kun allokerer objektet, men ikke gør yderligere. • En konstruktor invokeres således: new Klassenavn ( argumenter )
Metoder • Metoder i et objekt gør det muligt at ændre tilstanden eller kigge på tilstanden. • En metode består af programkode, som kan • opdatere og/eller vise indholdet af instansvariablene; • skabe nye objekter; • kalde metoder på sig selv eller andre objekter; • returnere en værdi. • En metodekald kan dermed: • have umiddelbar synlig effekt (uddata eller tegninger vises i et vindue, inddata læses fra et terminal eller en fil, etc.) • påvirke programmets interne tilstand ved opdatering/skabelse af et eller flere objekter.
Metodehoved char calc (int num1, int num2, String message) metodenavn parameterliste Parameterlisten specificerer type og navn for hvert parameter. Metodesignaturen består af: metodenavn efterfulgt af typerne af alle parametre (men ikke deres navne). returtype
Metodekrop • Efter metodehovedet kommer metodekroppen: char calc (int num1, int num2, String message) { int sum = num1 + num2; char result = message.charAt (sum); return result; } sum og result er lokale variable. Nye lokale variable allokeres automatisk hver gang metoden er kaldt og deallokeres automatisk når metoden returner. Returudtrykket skal være konsistent med returntypen.
char calc (int num1, int num2, String message) { int sum = num1 + num2; char result = message.charAt (sum); return result; } Parameteroverførsel Når en metode bliver kaldt (invokeret), kopieres argumenterne til parametrene i metoden, som svarer til variabeltildelinger. ch = obj.calc (25, count, "Hello");
compute myMethod myMethod(); Metodekald
main doIt helpMe obj.doIt(); helpMe(); Metodekald...
Virkefelt af lokale variable og parametre • Virkefeltet (eng. scope) for en variabel er den del af programmet hvor variablen er synlig og kan refereres (bruges): • en lokal variabel har virkefelt fra det sted, hvor den erklæres og til slutning af den blok den er erklæret i. • en lokal variabel erklæret lokal i en for-løkke har kun virkefelt i for-løkken • en parameter har virkefelt i hele metoden eller konstruktoren. • En lokal variabel skal være initialiseret før den må bruges.
Halvering igen public class Logarithm { // diskret logaritme base 2; // argument skal være positiv public static int log2f(int n) { for (int log=0; n>1; log++) n /= 2; return log; } Hvad er galt her?
Virkefelt af instansvariable • Eninstansvariabel har virkefelt i hele klassen, også tekstuelt før instansvariablens erklæring. • Men lokale variable og parametre kan skygge for instansvariable. • this kan benyttes til at tilgå`overskyggede' instansvariable. • Rækkefølgen af felt-erklæringer og deres placering i klassen erunderordnet. • Et felt behøver ikke at være initialiseret før det bruges. • Et felt initialiseres automatisk til 0 (int) eller 0.0 (double) eller '\000‘ (char) eller false (boolean) eller null (klasser).