Föreläsning 10, kapitel 10 Abstrahera mera! Abstrakta klasser och interface Kursbok: “Objects First with Java - A Practical Introduction using BlueJ”, David J. Barnes & Michael Kölling Fredric Ragnar Telefon Andreas Hedrén Telefon
Denna föreläsning Abstrakta klasser Interface Multipelt arv
Simuleringar Program används ofta för att simulera verkliga saker Stadstrafik Vädret Processer med atomkärnor Svängningar på aktiemarknaden Förändringar i miljön
Simuleringar, mer Ofta simulerar man bara en liten del av någonting Man gör ofta förenklingar Ju mer detaljrik en simulering är, ju större chans är det att resultatet är mer rätt. Ju mer detaljrik en simulering är, ju mer resurser kräver den : –Beräkningskraft –Tid att göra simuleringen
Varför simulera? Ett sätt att kunna göra förutsägelser –Vädret Tillåter att man experimenterar –Säkrare, billigare, snabbare Exempel: –Hur kommer djurlivet att förändras om vi drar en väg rakt igenom den här nationalparken?
Simulering av rov- och bytesdjur Det är ofta en fin balans mellan arterna Många bytesdjur betyder mycket mat Mycket mat tillåter flera rovdjur Fler rovdjur äter fler bytesdjur Färre bytesdjur betyder mindre mat Mindre mat betyder…
Projektet foxes-and-rabbits
De mest intressanta klasserna Fox –En enkel modell av ett rovdjur Rabbit –En enkel modell av ett bytesdjur Simulator –Sköter den övergripande simuleringen –Har en samling rävar och kaniner
Resten av klasserna Field –Representerar ett 2-D fält Location –Representerar en 2-D position SimulatorView, FieldStats, Counter –Underhåller statistik och presenterar en bild av fältet.
Hur det kan se ut
Tillståndet för en kanin public class Rabbit { Static fields omitted. // Individual characteristics (instance fields). // The rabbit's age. private int age; // Whether the rabbit is alive or not. private boolean alive; // The rabbit's position private Location location; Method omitted. }
En kanins beteende Sköts från metoden run Åldern ökas vid varje simuleringssteg –En kanin kan dö vid denna punkt Kaniner som är tillräckligt gamla kan föröka sig vid varje steg –Nya kaniner kan födas vid denna punkt
Förenklingar av kaniner Kaninerna har inte olika kön –I praktiken är alla honor Samma kanin kan föröka sig i varje steg Alla kaniner dör vid samma ålder Fler?
En rävs tillstånd public class Fox { Static fields omitted // The fox's age. private int age; // Whether the fox is alive or not. private boolean alive; // The fox's position private Location location; // The fox's food level, which is increased // by eating rabbits. private int foodLevel; Methods omitted. }
En rävs beteende Sköts från metoden hunt Rävar åldras och förökar sig de med De blir hungriga De jagar mat i närliggande positioner
Förenklingar av rävarna Liknande förenklingar som de hos kaninerna Att jaga och äta kan modelleras på många sätt –Skall tillgången på mat vara additiv? –Är det troligare att en hungrig räv jagar, eller är det mindre troligt? Kan man någonsin acceptera förenklingar?
Klassen Simulator Tre huvudsakliga delar Initiering i konstruktorn Metoden populate() –Varje djur får en slumpmässig ålder vid starten Metoden simulateOneStep() –Itererar över populationen –Två fältobjekt används: field och updatedField
Uppdateringssteget if(animal instanceof Rabbit) { Rabbit rabbit = (Rabbit)animal; rabbit.run(updatedField, newAnimals); } else if(animal instanceof Fox) { Fox fox = (Fox)animal; fox.hunt(field, updatedField, newAnimals); }
Saker som kan förbättras Fox och Rabbit har stora likheter men har ingen gemensam superklass Klassen Simulator är starkt bunden till de andra klasserna –Den vet mycket om hur rävar och kaniner beter sig.
Superklassen Animal Lägg gemensamma fält i Animal : –age, alive, location Döp om metoderna för att stötta ”information hiding”: run och hunt kallas nu act Simulator kan nu bli betydligt mindre hårt kopplad
Omarbetad mindre kopplad iteration for(Iterator iter = animals.iterator(); iter.hasNext(); ) { Animal animal = (Animal)iter.next(); animal.act(field, updatedField, newAnimals); }
Animal -klassens metod act Statisk typkontroll kräver att det finns en metod act i Animal Det finns ingen självklar gemensam implementation av act Definiera act som abstrakt: abstract public void act(Field currentField, Field updatedField, List newAnimals);
Abstrakta klasser och metoder Abstrakta metoder har abstract i signaturen Abstrakta metoder har ingen kropp Abstrakta metoder gör klassen abstrakt Abstrakta klasser kan inte instansieras (skapa sådana objekt) Konkreta subklasser kompletterar med implementation
Klassen Animal public abstract class Animal { fields omitted /** * Make this animal act - that is: make it do * whatever it wants/needs to do. */ abstract public void act(Field currentField, Field updatedField, List newAnimals); other methods omitted }
Ytterligare abstraktion
Selektiv utritning (multipelt arv)
Multipelt arv Låta en klass ärva direkt av flera förfäder Varje språk har sina regler –Hur löser man motstridiga definitioner? Java förbjuder multipelt arv för klasser Java tillåter multipelt arv för interface –Inga motstridiga implementationer
Ett Actor -interface public interface Actor { /** * Perform the actor's daily behavior. * Transfer the actor to updatedField if it is * to participate in further steps of the simulation. currentField The current state of the field. location The actor's location in the field. updatedField The updated state of the field. */ void act(Field currentField, Location location, Field updatedField); }
Klasser implementerar interface public class Fox extends Animal implements Drawable {... } public class Hunter implements Actor, Drawable {... }
Interface som typer Klasser som implementerar ärver inte kod, men… Klasser som implementerar är subtyper av interfacets typer Alltså: polymorfism finns hos interface precis som hos klasser
Interface som specifikation Klar separation av funktionalitet och implementation –Fast det krävs parameter- och returvärdestyper Klienter jobbar mot gränssnittet oberoende av implementationen –Men klienter kan välja mellan olika implementationer
Alternativa implementationer
Summering arv Arv kan ge delad implementation –Konkreta och abstrakta klasser Arv ger delad typinformation –Klasser och interface
Summering abstrakta klasser Abstrakta metoder tillåter statisk typkontroll utan att det krävs en implementation Abstrakta klasser fungerar som superklasser som inte är kompletta –Inga instanser Abstrakta klasser stödjer polymorfism
Summering interface Interface tillhandahåller specifikation utan en implementation –Interface är helt abstrakta Interface stödjer polymorfism Javas interface stödjer multipelt arv