390 likes | 555 Views
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 fredric.ragnar@hgo.se Telefon 0498-299948 Andreas Hedrén andreas.hedren@hgo.se Telefon 0498-299954.
E N D
Föreläsning 8, kapitel 8 Förbättra strukturen med arvKursbok: “Objects First with Java- A Practical Introduction using BlueJ”, David J. Barnes & Michael Kölling Fredric Ragnar fredric.ragnar@hgo.se Telefon 0498-299948 Andreas Hedrén andreas.hedren@hgo.se Telefon 0498-299954
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
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() { ... } ... } Källkod för klassen CD 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() { ... } ... } Källkod för klassen Video Inte komplett (kommentarer!)
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 } } } Källkod för klassen Database
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, 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
Arv i Java Ingen ändring här public class Item { ... } Ändra här public class Video extends Item { ... } public class CD extends Item { ... }
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. }
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
public class CD extends Item { private String artist; private int numberOfTracks; /** * Constructor for objects of class CD */ public CD(String theTitle, StringtheArtist, int tracks, int time) { super(theTitle, time); artist = theArtist; numberOfTracks = tracks; } // methods omitted } Arv och konstruktorer, mer
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
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!
/** * 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 } } Ny källkod för klassen Database
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 Objekt ur en subklass kan tilldelas till superklass variabler Vehicle v1 = new Vehicle(); Vehicle v2 = new Car(); Vehicle v3 = new Bicycle();
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
Polymorfa variabler • Objektvariabler i Java är polymorfaDe 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 typ wrapper-klass int Integer float Float char Character ... ...
Wrapper-klasser, ännu mer packa int-värdet I ett objekt int i = 18; Integer iwrap = new Integer(i); myCollecton.add(iwrap); ... Integer element = (Integer) myCollection.get(0); int value = element.intValue() 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)