Præsentation er lastning. Vent venligst

Præsentation er lastning. Vent venligst

Selve objektet versus referencen til objektet Nedarvning

Lignende præsentationer


Præsentationer af emnet: "Selve objektet versus referencen til objektet Nedarvning"— Præsentationens transcript:

1 Selve objektet versus referencen til objektet Nedarvning
Objekter, Klasser, Polymorfi Opsamling GP fredag den 7. november 2003 kl. 9 – 9.45 Oversigt Klasse versus objekt Klassehierarkier Selve objektet versus referencen til objektet Nedarvning Overskrivning af metoder Polymorfi Abstrakte klasser Interfaces toString() og equals()

2 Klasse versus Objekt En klasse repræsenterer et begreb: tidspunkt, aftale, køretøj, bil, cykel, dyr, ko, person, beholder, tønde… Et objekt repræsenterer en ting, en instans af et begreb: et bestemt tidspunkt, en bestemt bil, en bestemt cykel, en bestemt ko, en bestemt person… Klasse Objekt Hest hest1:Hest :Hest

3 Klassehierarkier Nogle begreber er beslægtede (f.eks. køretøj, bil og cykel; eller dyr og ko; eller beholder og tønde). Det er naturligt at forsøge at ordne begreberne i hierarkier: dyr kan opdeles i ’pattedyr’, ’fisk’, ’fugl’… køretøj kan opdeles i ’bil’, ’cykel’, ’lastvogn’… beholder kan opdeles i ’tønde’, ’tank’, ’trug’… Vi forsøger ofte at beskrive verden ved hjælp af begrebshierarkier. I Java og mange andre objektorienterede programmeringssprog modellerer man ved hjælp af klassehierarkier. En klasse B kan udvide en eksisterende klasse A. Klassen A er superklasse til B, og B er subklasse til A.

4 Eksempel på klassehierarki
(tegnet i UML)

5 Selve Objektet versus Referencen til Objektet
Klasser fungerer som skabeloner for objekter. Man siger, at objektet har (eller hører til) en bestemt klasse Referencer er også defineret ved en klasse. Man siger at referencen har en type ved navn klassenavn. I Java kan vi oprette objekter med et udtryk, der består af følgende led: referencetype referencenavn = new objekttype ([argumenter]); En reference af typen T kan pege på objekter hørende til klassen T og dens subklasser. F.eks Hest hest1 = new Hest(); I dette tilfælde er både referencetype og objekttype den samme – nemlig Hest hest1:Hest :Hest

6 Men vi kunne også have valgt at lade hest1 være en araber hest:
Hest hest1 = new Araber(); Nu er objektet af typen Araber, men referencen er stadig af type Hest. :Araber hest1:Hest

7 Vi kunne såmænd også lade referencen være af typen Dyr:
Dyr hest1 = new Araber(); Nu er objektet stadig af typen Araber, men referencen er af typen Dyr. :Araber hest1:Dyr

8 Opgaver – objekter og referencer
Er følgende initialiseringer lovlige: Araber h1 = new Hest(); Hest h1 = new Araber(); Fisk f1 = new Dyr(); Dyr d1 = new Pattedyr(); Dyr d2 = new Hest(); Dyr d3 = new Islænder();

9 En subklasse arver felter og metoder fra sin superklasse.
Nedarvning En subklasse arver felter og metoder fra sin superklasse. En subklasse kan derudover definere nye felter og metoder, eller omdefinere (overskrive) nedarvede metoder – det er grundlaget for polymorfi. private metoder og felter: Hvis et felt (eller en metode) er private i en superklasse A, så kan det ikke benyttes i subklasser af A.Feltet arves dog alligvel: det findes i subklassens objekter. Ellers ville det jo ikke kunne benyttes i metoder, der arves fra superklassen. Arves konstruktorer? Nej, konstruktorer arves ikke. Men det første en subklasses konstruktor gør, er at kalde en konstruktor for superklassen. Dette kan gøres eksplicit med et kald af formen super(…). Hvis ikke det gøres eksplicit, så underforstås et kald super() til en argumentløs konstruktor. I det tilfælde er superklassen altså nødt til at have en argumentløs konstruktor. Sådan en findes automatisk, hvis man ikke definerer andre konstruktorer. Overskrives felter? Nej. Hvis subklassen erklærer et felt f som også findes i superklassen, så får man to felter med samme navn. Det er næsten altid forkert og resulterer i forvirring og hovedbrud. Omdefinér kun metoder, ikke felter. (Feltet arvet fra superklassen kan dog tilgås som super.f, mens subklassens felt blot hedder f).

10 Overskrivning af metoder
En subklasse kan omdefinere en metode, der ellers ville blive arvet fra en superklasse. I mit bearbejdede dyre-hierarki har jeg givet Dyr en metode: lavKaldeLyd(). Alle klasser, der nedarver fra Dyr, arver denne lavKaldeLyd() metoden, hvis ikke de overskriver den. Araber og Islænder arver dog metodeimplementationen fra Hest. Hest-klassen har jeg udvidet en del. Jeg har bestemt, at en hest i mit program altid skal have et navn, og derfor har den fået sit eget klassefelt, navn. Det har den konsekvens, at Hest har fået en konstruktor med en parameter. Derudover har Hest-klassen sin egen metode, stejl().

11 Bearbejdet dyrehierarki

12 class Dyr{ public void lavKaldeLyd(){ System.out.println(”Dyrelyd”); } class Fugl extends Dyr{ System.out.println("Pip"); class Fisk extends Dyr{ System.out.println("Glob"); class Pattedyr extends Dyr{ class Ko extends Pattedyr{ System.out.println("Muh"); class Hest extends Pattedyr{ public String navn; public Hest(String n){ navn = n; } public void lavKaldeLyd(){ System.out.println("Vrinsk"); public void stejl(){ System.out.println(”Stejler"); class Araber extends Hest{ public Araber(String n){ super(n); class Islænder extends Hest{ public Islænder(String n){

13 Polymorfi Når man kalder en metode på et objekt, er det objektets klasse, der bestemmer hvilken metode, der kaldes, men det er referencens type, der afgør om man må kalde metoden. Altså givet følgende udtryk: Dyr d1 = new Hest(”Sally”); er det lovligt at skrive: d1.lavKaldeLyd(); hvorved implementationen af lavKaldeLyd() fra Hest klassen eksekveres. Mens d1.stejl(); ikke er lovligt selvom metoden findes i Hest-klassen. Det skyldes at den ikke findes i Dyr-klassen.

14 Test af Dyre hierarkiet
public class PolymorfiTest{ public static void main(String[] args){ Dyr[] zoo = new Dyr[5]; Dyr ko1 = new Ko(); Dyr fugl1 = new Fugl(); Dyr fisk1 = new Fisk(); Dyr hest1 = new Hest("Beauty"); Dyr hest2 = new Hest("Plet"); zoo[0] = ko1; zoo[1] = fugl1; zoo[2] = fisk1; zoo[3] = hest1; zoo[4] = hest2; for(int i = 0; i < zoo.length; i++){ zoo[i].lavKaldeLyd(); } Bemærk at det kun er muligt at samle objekter af typen Ko, Fugl, Fisk og Hest i et Array fordi der er en fælles supertype. Output: Muh Pip Glob Vrinsk

15 Opgaver - polymorfi Givet følgende objekter: Dyr d1 = new Fugl();
h1 a1 :Fugl +lavKaldeLyd() :Hest +navn:String +lavKaldeLyd() +stejl() :Araber +navn:String +lavKaldeLyd() +stejl() :Araber +navn:String +lavKaldeLyd() +stejl() Givet følgende objekter: Er det da lovligt at skrive: Dyr d1 = new Fugl(); Dyr d2 = new Hest(”Klaus”); Hest h1 = new Araber(”Storm”); Araber a1 = new Araber(”Sheik”); d1.lavKaldeLyd() d2.stejl() h1.stejl() a1.stejl() d2.navn h1.navn a1.navn

16 En abstrakt klasse kan ikke instantieres.
Abstrakte klasser En klasse kan erklæres abstrakt. Så modellerer den typisk et abstrakt begreb. En abstrakt klasse kan have abstrakte metoder (– den kan også have konkrete metoder). En abstrakt klasse kan ikke instantieres. I mit dyre hierarki kunne jeg lade Dyr være en abstrakt klasse. Hermed siger jeg, at et Dyr ikke bare kan være et Dyr, men skal være et mere specifikt Dyr – nemlig en subklasse af Dyr. Jeg kunne også lade lavKaldeLyd() være en abstrakt metode. Så skal alle subklasser overskrive denne abstrakte metode eller selv være abstrakt. abstract class Dyr{ abstract void lavKaldeLyd(); }

17 Interfaces (Klassegrænseflader)
I visse objektorienterede sprog kan en klasse have flere superklasser. Det kan føre til teoretiske og praktiske problemer. (Eks: I hvilken rækkefølge skal superklassernes konstruktorer kaldes?) (Eks: Hvis to metoder med samme signatur arves fra to forskellige superklasser, hvilken en skal så bruges?) Java har enkel nedarvning: en klasse kan kun have én umiddelbar superklasse. Interfaces er en erstatning for multipel nedarvning. Et interface kan opfattes som en ultra-abstrakt klasse. Et interface kan kun erklære felter der er konstante. Derfor er nøgleordene final og static underforståede (men må gerne skrives). Et interface kan kun erklære metoder, der er abstrakte og synlige overalt. Derfor er nøgleordene abstract og public underforståede (men må gerne skrives). En metode beskrevet i en grænseflade, skal være public i klasser, der implementerer grænsefladen. Et interface kan ikke erklære konstruktorer. En klasse kan implementere vilkårlig mange interfaces (men stadig kun udvide én superklasse). For at implementere et interface skal klassen implementere alle interfacets metoder.

18 Polymorfi – hvorfor Polymorfi tillader os at skabe et begrebshierarki via nedarvning samt at manipulere objekter i dette hierarki gennem deres fælles baseklasse. Superklassen udgør den fælles grænseflade for alt det, som nedarver fra den. De nedarvede klasser kan overskrive definitionerne fra superklassen og på den vis have deres egen unikke adfærd. Polymorfisme lader os behandle alle objekter i et hierarki generisk, hvilket betyder at store dele af koden ikke behøver være afhængig af en specifik type-information. Pointen skulle være, at det gør programmer mere udvidbare (extensible), og den egenskab medfører, at det at bygge programmer og vedligeholde programmer er billigere og lettere. Polymorfisme skulle desuden lægge op til bedre organisering af kode og læsbarhed. For at kunne udnytte herlighederne ved polymorfi gælder det altså om at få defineret sine metoder så højt oppe i hierarkiet som muligt -> lave så generelle metoder som muligt.

19 Polymorfi – toString()
Alle klasser i Java er subklasser af klassen Object. Det er underforstået og behøver ikke blive skrevet i klasse-erklæringerne public class Dyr extends Object{ … } Alle klasser arver visse metoder fra Object herunder en universel udgave af metoden toString(). Med universal-udgaven kan d2.toString() give noget, der ligner Det er objektets klasse efterfulgt af objektets adresse i maskinens lager (angivet i sekstentalssystemet). Definerer vi en metode toString i klassen Hest, så overskriver den toString arvet fra klassen Object.

20 Implementering af toString() metoden
class Ko extends Pattedyr{ public String toString(){ return "Jeg er en ko"; } (Tilsvarende for fugl og fisk) class Hest extends Pattedyr{ return "Jeg er en hest ved navn: " + navn; class Araber extends Hest{ return "Jeg er en araberhest ved navn: " + navn; class Islænder extends Hest{ return "Jeg er en islænderhest ved navn: " + navn;

21 Jeg er en hest ved navn: Beauty Jeg er en araberhest ved navn: Plet
public class PolymorfiTest{ public static void main(String[] args){ Dyr[] zoo = new Dyr[]{new Ko(), new Fugl(), new Fisk(), new Hest("Beauty"), new Araber("Plet")}; for(int i = 0; i < zoo.length; i++){ System.out.println(zoo[i].toString()); } Output: Jeg er en ko Jeg er en fugl Jeg er en fisk Jeg er en hest ved navn: Beauty Jeg er en araberhest ved navn: Plet

22 Polymorfi - equals() metoden
Klassen Object har også en metode ved navn equals(), hvilket betyder at alle klasser har en equals() metode, som de nedarver fra Object. Ifølge denne standard implementation returnerer equals() true, hvis de to objekter, der sammenlignes er identiske. Dyr d1 = new Araber(”Prince”); Dyr d2 = new Araber(”Prince”); d1.equals(d2) returnerer false, idet der er tale om to forskellige objekter. d1 :Araber navn=”Prince” d2 :Araber navn=”Prince”

23 Implemetering af equals() metoden
Tanken med equals() er dog, at metoden skal returnere sand, hvis to objekter er ens ifølge den definition af ens, som skaberen af den enkelte klasse giver. Dvs. at vil man have en equals metode i sine klasser, som fungerer efter hensigten, skal man selv implementere den. class Araber{ public boolean equals(Object o){ Araber a2 = (Araber) o; return (navn.equals(a2.navn)); } Test: Araber a1 = new Araber(”Prince"); Araber a2 = new Araber(”Prince"); System.out.println("a1.equals(a2): ” + a1.equals(a2)); System.out.println("a1 == a2: ” + (a1 == a2))); Output: a1.equals(a2): true a1 == a2: false


Download ppt "Selve objektet versus referencen til objektet Nedarvning"

Lignende præsentationer


Annoncer fra Google