Klasshierarkier - repetition Klasser kan byggas på redan denierade klasser, egna och/eller färdigskrivna, genom: I att klassobjekt används som attribut (instansvariabler): har-relation. Exempel: traksystemet har tre Lanes och två Lights public class TrafficSystem { private Lane r0; private Lane r1; private Lane r2; private Light s1; private Light s2; //metoder... Eller I arv, är-relation. Exempel: SyntaxException är ett RuntimeException public class SyntaxException extends RuntimeException (2009-04-28 7.1 )
Klasshierarkier - repetition Exempel på har-relation: TrafficSystem r0: Lane r1: Lane r3: Lane s1: Light s2: Light ============== //metoder... Light period: int green: int time: int ========= //metoder Lane thelane [] Vehicle ============== //metoder Vehicle borntime: int destination: char ============= //metoder (2009-04-28 7.2 )
Klasshierarkier - repetition Exempel på är-relation: Fordon maxhastighet:double Spark Cykel växel : int växla(int) : void Bil vikt : double Personbil pantal : int Lastbil maxlast : double (2009-04-28 7.3 )
Klasshierarkier - repetition Terminologi I basklass subklass I en subklass är en specialiseringar/utökning av basklassen: en subklass är en basklass som... I en subklass ärver alla attribut och metoder från basklassen (från alla nivåer) I en subklass kan skriva över (dölja) basklassens attribut och metoder samt, naturligtvis, tillfoga egna (2009-04-28 7.4 )
Repetition forts I kod: nyckelordet är extends public class Fordon { double maxhastighet = 100; public void print() { System.out.print("Fordon"); public class Cykel extends Fordon { double maxhastighet = 45; int växel = 1; public void print() { System.out.print("Cykel med " + växel + " växlar"); public void växla(int v) { växel = v; public class Spark extends Fordon { (2009-04-28 7.5 )
Skyddsnivåer I private Endast åtkomligt från klassens egna metoder I public Åtkomligt för alla I protected Åtkomligt från egna subklasser och klasser i samma paket I package Om ingen skyddsnivå anges så ges alla klasser i samma paket åtkomsträttighet (2009-04-28 7.6 )
Konstruktorer, ett exempel Konstruktorer ärvs inte men basklassens konstruktorer kan anropas med super. public class Fordon { double maxhastighet = 100; public Fordon (double mh) { maxhastighet = mh; //mer kod... public class Cykel extends Fordon { int växel = 1; public Cykel(int v, double mh) { super(mh); //anropar konstruktor i basklassen växel = v; public Cykel(int v) { this(v,50); //anropar konstruktor i den egna klassen //mer kod... (2009-04-28 7.7 )
Konstruktorer vid arv Konstruktorer ärvs inte När ett objekt ur en subklass skapas så sker följande: 1. Instansvariablerna får sina defaultvärden 2. En konstruktor för superklassen anropas. Man använder super för att specicera vilken av basklassens konstruktor som skall användas. Om super inte används anropas basklassens parameterlösa konstruktor som då måste nnas. 3. Eventuella initieringsuttryck evalueras och tilldelas respektive instansvariabler 4. Satserna i subklassens konstruktor exekveras Använd super i stället för att upprepa kod! (2009-04-28 7.8 )
Mer arv För att referenserna till metoden m och attributet a i koden class C extends B {...... C r = new C(); r.m(); r.a = 4; skall vara korrekta så måste m och a vara deklarerade i klassen C eller i någon basklass till C (t ex i B) (2009-04-28 7.9 )
Mer arv En variabel deklarerad att referera objekt av en viss klass får också referera objekt av klassens subklasser (men inte tvärtom). Exempel: Cykel c = new Cykel(); //Tillåtet Fordon f = new Cykel(); //Tillåtet I Om en metod är denierad på era nivåer så är det objektets verkliga typ som används vid valet av variant (dynamisk eller sen bindning) Exempel: f.print(); // Cykelklassens print-metod anropas. c.print(); // Cykelklassens print-metod anropas. I Om ett attribut är denierat på era nivåer så är det deklarationen av referensen som avgör vilket som väljs (statisk eller tidig bindning) Exempel: System.out.println(f.maxHastighet); // Fordonklassens attribut System.out.println(c.maxHastighet); // Cykelklassens attribut (2009-04-28 7.10 )
Metoder som bara nns i vissa klasser Fordon maxhastighet: double Spark Cykel växel : int växla(int) : void Bil vikt : double Personbil pantal : int skatt() : double Lastbil maxlast : double skatt() : double Bilar beskattas men beräkningen görs på olika sätt för person- och lastbilar. (2009-04-28 7.11 )
Användning av skatt-metoden Bil b = new Lastbil(3., 2.);... if (...) { b = new Personbil(1.2, 5);... double s; s = b.skatt(); s = ((Lastbil) b).skatt(); // Illegalt! Skatt inte finns i b // Riskabelt! Fungerar ej om if utförts if ( b instanceof Lastbil ) // OK men klumpigt och s = ((Lastbil) b).skatt(); // oflexibelt else if ( b instanceof Personbil ) s = ((Personbil) b).skatt(); else s = 0; (2009-04-28 7.12 )
Använd polymorsm - sen bindning (dynamisk bindning) Fråga: varför är inte skatt en instansvariabel? OBS! compare-metoderna har alla ett Fordon-objekt i parameterlistan => sen bindning. Fordon ================== ------------------------------- skatt() : double compare(fordon): void Cykel ================= växel: int ------------------------------ skatt() : double compare(fordon): void Bil ================= ------------------------------ skatt() : double compare(fordon): void Personbil ================= pantal : int ------------------------------ skatt() : double print : void compare(fordon): void Lastbil ================== maxlast : double ------------------------------- skatt() : double print : void compare(fordon) : void (2009-04-28 7.13 )
Använd polymorsm - sen bindning (dynamisk bindning) public class Fordon { public double skatt() { return 50; public void compare (Fordon annat) { System.out.println("Fel."); //mer kod... public class Bil extends Fordon { public double skatt() { return 40; public void compare(fordon annat) { if (this.skatt() > annat.skatt()) System.out.println("Bilen betalar mer: " + this.skatt()); else if (this.skatt() == annat.skatt()) System.out.println("De betalar lika mycket."); else System.out.println("Den andra betalar mer."); //mer kod... (2009-04-28 7.14 )
Använd polymorsm - sen bindning (dynamisk bindning) public class Lastbil extends Bil { double maxlast; public double skatt() { return 30; public void compare(fordon annat) { if (this.skatt() > annat.skatt()) System.out.println("Lastbilen betalar mer:" + this.skatt()); else if (this.skatt() == annat.skatt()) System.out.println("De betalar lika mycket."); else System.out.println("Den andra betalar mer."); //mer kod... (2009-04-28 7.15 )
Använd polymorsm - (fortsättning) public class TestFordon { public static void main(string[] arg) { Bil b = new Bil(); Lastbil l = new Lastbil(); Fordon f = new Bil(); System.out.print("Jämför bilen med lastbilen: "); b.compare(l); System.out.print("Jämför bilen med fordonet: "); b.compare(f); System.out.print("Jämför lastbilen med fordonet: "); l.compare(f); Typen på compare-metodens parameter bestäms av java-interpretatorn, inte vid kompilering. Utskrift från programkörning: Jämför bilen med lastbilen: Bilen betalar mer: 40.0 Jämför bilen med fordonet: De betalar lika mycket. Jämför lastbilen med fordonet: Den andra betalar mer. (2009-04-28 7.16 )
OOP, objektorienterad programmering De tre viktigaste programmeringsmekanismerna för OOP: I inkapsling I arv I polymorsm <> sen bindning: variablers förmåga att ha mer än en typ, vilket tillåter olika objekt exibiliteten att svara olika på samma anrop. (2009-04-28 7.17 )
Standardprogramvara i Java Hela Java-miljön bygger på arv och klasshierakier! Exempel: 1. Klasserna för undantag: Throwable med underklasserna Error och Exception med underklasserna... 2. Graska komponenter: Component med underklasser Button, Checkbox, Container,... där t ex Container har underklasserna Panel, Window... 3. Avbildningar: Map med bl a underklassen HashMap 4. Samlingsklasserna: Collection med bl a underklassen och List som bl a har underklasserna Vector och LinkedList (Map, Collection och List är egentligen interface och inte klasser) (2009-04-28 7.18 )
Arv - abstrakta metoder och klasser Det nns ingen meningsfull implementation av print() och compare() i Fordon! Deklarera dessa metoder och klassen Fordon som abstract. Inget fordon är bara ett fordon, det är antingen en bil eller en cykel eller... //klassen måste deklareras abstract eftersom den har abstrakta metoder public abstract class Fordon { public double skatt() { return 50; public abstract void compare (Fordon annat); //en abstrakt metod public abstract void print(); //en abstrakt metod (2009-04-28 7.19 )