Föreläsning 8, kapitel 8 Förbättra strukturen med arv Kursbok: “Objects First with Java - A Practical Introduction using BlueJ”, David J. Barnes & Michael Kölling Fredric Ragnar Telefon Andreas Hedrén Telefon
Dagens punkter Arv Subtyping Substitution Polymorfa variabler
DoME exemplet "Database of Multimedia Entertainment" Lagrar detaljer om CD-skivor och videofilmer CD: titel, artist, antal spår, speltid, har den, kommentar Video: titel, regissör, speltid, har den, kommentar Tillåter (senare) att söka efter information eller skriva ut listor
Objekt i DoME
Klasser i DoME
Objektmodell för DoME
Klassdiagram för DoME
Källkod för klassen CD public class CD { private String title; private String artist; private String comment; CD(String theTitle, String theArtist) { title = theTitle;artist = theArtist;comment = " "; } void setComment(String newComment) {... } String getComment() {... } void print() {... }...} Inte komplett (kommentarer!)
public class Video { private String title; private String director; private String comment; Video(String theTitle, String theDirect) { title = theTitle;director = theDirect;comment = " "; } void setComment(String newComment) {... } String getComment() {... } void print() {... }...} Inte komplett (kommentarer!) Källkod för klassen Video
Källkod för klassen Database class Database { private ArrayList cds ; private ArrayList videos ;... public void list() { for(Iterator iter = cds.iterator(); iter.hasNext(); ) { CD cd = (CD)iter.next(); cd.print(); System.out.println(); // empty line between items } for(Iterator iter = videos.iterator(); iter.hasNext(); ) { Video video = (Video)iter.next(); video.print(); System.out.println(); // empty line between items }
Kritik av DoME Duplicering av kod Klasserna CD och Video är väldigt lika, stora delar t o m identiska Gör underhåll svårt/mer jobb Inför risk för buggar genom felaktigt underhåll Det finns också duplicerad kod i klassen Database
Använda arv
Använda arv, mer Definiera en superklass: Item Definiera subklasser för Video och CD Superklassen definierar gemensamma attribut Subklasserna ärver superklassens attribut Subklasserna lägger till egna attribut
Arvshierarkier
Arv i Java public class Item {... } public class CD extends Item {... } public class Video extends Item {... } Ingen ändring här Ändra här
Superklassen Item public class Item { private String title; private int playingTime; private boolean gotIt; private String comment; // constructors and methods omitted. }
Underklasserna CD och Video public class CD extends Item { private String artist; private int numberOfTracks; // constructors and methods omitted. } public class Video extends Item { private String director; // constructors and methods omitted. }
Arv och konstruktorer public class Item { private String title; private int playingTime; private boolean gotIt; private String comment; /** * Initialise the fields of the item. */ public Item(String theTitle, int time) { title = theTitle; playingTime = time; gotIt = false; comment = ""; } // methods omitted }
Arv och konstruktorer, mer public class CD extends Item { private String artist; private int numberOfTracks; /** * Constructor for objects of class CD */ public CD(String theTitle, String theArtist, int tracks, int time) { super(theTitle, time); artist = theArtist; numberOfTracks = tracks; } // methods omitted }
Anrop av superklassens konstruktor Subklassernas konstruktorer måste alltid ha ett ”super” anrop Om det inte finns i källkoden så lägger kompilatorn till ett ”super”-anrop (utan parametrar) –Funkar bara om superklassen har en konstruktor utan parametrar Måste vara den första satsen i subklassens konstruktor
Lägger till flera Item typer
Djupare hierarkier
Summering Vitsen med arv vad vi hittills sett: Att undvika duplicering av kod Återanvändning av kod Lättare underhåll Möjlighet att utöka
Ny källkod för klassen Database public class Database{ private ArrayList items; /** * Construct an empty Database. */ public Database() { items = new ArrayList(); } /** * Add an item to the database. */ public void addItem(Item theItem) { items.add(theItem); }...} undviker duplicering av kod i klienten!
Ny källkod för klassen Database /** * Print a list of all currently stored CDs and * videos to the text terminal. */public void list(){ for(Iterator iter = items.iterator(); iter.hasNext(); ) { Item item = (Item)iter.next(); item.print(); System.out.println(); // empty line between items }
Subtypning Först hade vi: public void addCD(CD theCD) public void addVideo(Video theVideo) Nu har vi: public void addItem(Item theItem) Vi anropar den här metoden med: Video myVideo = new Video(...); database.addItem(myVideo);
Subklasser och subtypning Klasser definierar typer Subklasser definierar subtyper Objekt av subklasser kan användas där objekt av superklasser krävs (Detta kallas substitution)
Subtypning och tilldelning Vehicle v1 = new Vehicle();Vehicle v2 = new Car();Vehicle v3 = new Bicycle(); Objekt ur en subklass kan tilldelas till superklass variabler
Subtypning och parametrar public class Database { public void addItem(Item theItem) {... } Video video = new Video(...); CD cd = new CD(...); database.addItem(video); database.addItem(cd); Objekt ur en subklass kan användas som parametrar som är objekt ur en superklass
Objektdiagram
Klassdiagram
Polymorfa variabler Objektvariabler i Java är polymorfa De kan innehålla objekt av mer än en typ De kan innehålla objekt av den deklarerade typen, eller objekt av subtyper av den deklarerade typen.
Klassen Object Alla klasser ärver från Object.
Polymorfa samlingar Alla samlingar (collections) är polymorfa Elementen är av typen Object public void add(Object element) public Object get(int index)
Casting, igen Kan tilldela subtyp till supertyp Kan inte tilldela supertyp till subtyp String s1 = myList.get(1); fel! Casting fixar detta: String s1 = (String) myList.get(1); Bara om elementet verkligen är en String.
Wrapper-klasser Alla objekt kan stoppas in i en samling… …eftersom samlingar klarar element av typen Object… … och alla klasser är subtyper till Object Great! Men primitiva typer då?
Wrapper-klasser, mer Primitiva typer (int, char, etc) är inte objekt. De måste ”slås in”/”wrappas” i ett objekt. Wrapper-klasser finns för alla primitiva typer primitiv typwrapper-klass intInteger floatFloat charCharacter...
Wrapper-klasser, ännu mer int i = 18; Integer iwrap = new Integer(i); myCollecton.add(iwrap);... Integer element = (Integer) myCollection.get(0); int value = element.intValue() packa int-värdet I ett objekt Lägg till objektet Plocka ut värdet igen
Summering Arv tillåter att klasser definieras som utökningar av andra klasser Arv: –Undviker duplicering av kod –Tillåter återanvändning av kod –Förenklar koden –Förenklar underhåll och tillägg Variabler kan referera till objekt av subtyper Subtyper kan användas överallt där objekt av superklassen förväntas (substitution)