210 likes | 378 Views
Objektorienteret programmering. Indkapsling Arv og polymorfi (OOP’s 3 hovedprincipper). OO-Principper -indkapsling. Et objekt er (set udefra) en atomar enhed der tilbyder en række services (metoder/properties).
E N D
Objektorienteret programmering Indkapsling Arv og polymorfi (OOP’s 3 hovedprincipper) NOEA - Nordjyllands Erhvervsakademi
OO-Principper-indkapsling • Et objekt er (set udefra) en atomar enhed der tilbyder en række services (metoder/properties). • Det at gøre detaljerne i objekters implementation utilgængelige kaldes information hiding. • Det at gruppere data sammen med operationer på disse data under praktisering af information hiding kaldes indkapsling eller dataabstraktion. • Indkapsling er et af hovedprincipperne i OOP NOEA - Nordjyllands Erhvervsakademi
OO-Principper-nedarvning • Alle metoder bortset fra constructors arves. • private medlemmer af basisklassen nedarves, men kan ikke tilgås direkte. • Alle protected medlemmer af basisklassen er synlige nedad i arvehierakiet, men private for alle klasser udenfor. • Der kan tilføjes attributter og metoder i den nedarvede klasse • Ingen multipel arv • I C# arver alle klasser fra object NOEA - Nordjyllands Erhvervsakademi
OO-Principper-nedarvning • Nedarvning understøtter kodegenbrug • Nedarvning gør det muligt at udvide en eksisterende klasse. • Nedarvning er typespecialisering, dvs. vi modellerer et ”er-en” forhold mellem den nedarvede klasse og den der arves fra - fx: en Checkkonto er-en Konto. • Hvis vi står og mangler en klasse som er en specialisering af en klasse vi har, kan vi anvende nedarvning. • Fx Konto -> CheckKonto NOEA - Nordjyllands Erhvervsakademi
OO-Principper-nedarvning • Den der arves fra kaldes basisklasse/superklasse. • Den der arver kaldes subklasse • Husk at der gælder et er-en forhold mellem sub- og basisklassen • En nedarvet klasse er typekompatibel med basisklassen: CheckKonto ck = new CheckKonto(); If (ck is Konto) //returnerer true hvis CheckKonto arver fra Konto • Er-en forholdet er transitivt. NOEA - Nordjyllands Erhvervsakademi
Udvidelse af domænemodellen Kode NOEA - Nordjyllands Erhvervsakademi
Nedarvning - Constructors • Basisdelen af en nedarvet klasse initialiseres ved kald til base(param-liste). • Kald til forfaders constructor er det første der sker i den nedarvede klasses constructor. • :base(param-liste) placeres umiddelbart efter constructorens metodehoved – notation taget fra C++ • Hvis man ikke definerer en constructor, genereres en default. Ved nedarvning kalder denne implicit en default constructor (parameterløs) på basisklassen. NOEA - Nordjyllands Erhvervsakademi
Nedarvning - redefinering • En basisklasse-metode kan redefineres i den nedarvede klasse • Fx Haev-metoden på en Konto/CheckKonto • En basisklasse-metode der skal redefineres i den nedarvede klasse, skal erklæres virtual i basisklassen, og eksplicit overrides i den nedarvede klasse. • En override-metode tilsidesætter basisklassens metode. • Metoden i den nedarvede klasse skal have samme signatur og returtype som den virtuelle den redefinerer. • En redefineret metode kan kalde den metode den redefinerer i superklassens vha. base.metodenavn(); NOEA - Nordjyllands Erhvervsakademi
Nedarvning - polymorfi • Alle referencevariabler i C# kan referere objekter af nedarvede typer – (polymorf = mange former). • Ved virtuelle metoder træffes der beslutning på run-time om hvilken metode der skal kaldes. • Metoden der kaldes er den der er defineret på det objekt referencen i øjeblikket refererer. • Dette kaldes dynamisk binding. NOEA - Nordjyllands Erhvervsakademi
Polymorfi/Dynamisk binding Statisk type Dynamisk type Som vi plejer at se det: Ansat programmør = new Ansat("KodeKarl","Programmør",22222); Statisk type = Dynamisk type Statisk metodekald Statisk type Dynamisk type • Med polymorft typesystem: • Ansat chef = new Chef(”Bosse",”Direktør",52525, 500); • Dynamisk type er samme som eller arving til statisk type • Compiler checker på statisk type om metode eksisterer, kald til metode vha. dynamisk binding • Dynamisk binding forudsætter at metoder er erklæret virtual NOEA - Nordjyllands Erhvervsakademi
Polymorfi – brug af ArrayList • ArrayList indeholder elementer af den statiske type Object Eksplicit cast Implicit cast • Den statiske type checkes af compileren – derfor cast • Den dynamiske type bestemmes run-time • Den dynamiske type skal være lig den statiske eller en subtype (dvs. nedarvet fra) til den statiske • Ved et metodekald startes (ved dynamisk binding) med at kigge efter metoden i den dynamiske type • Derefter ledes efter metoden opad gennem arvehierarkiet foreach(Ansat ans in ansatte) ans.GivBonus(10000); for(int i= 0;i<ansatte.Count;i++) ((Ansat)ansatte[i]).GivBonus(10000); NOEA - Nordjyllands Erhvervsakademi
Eksempel • Lad os implementere domænemodellen fra før: NOEA - Nordjyllands Erhvervsakademi
Øvelse • Lav opgave 1 og 2 i KontoOpgave.htm NOEA - Nordjyllands Erhvervsakademi
Substitutionsprincippet • Den dynamiske type skal altid kunne bruges i stedet for den statiske • Dvs., at objekter af en nedarvet type skal kunne anvendes i stedet for objekter af den oprindelige • De skal kunne substitueres • Dette sikres ved at vi ved redefinering af methoder kun afsvækker pre-betingelser og strammer post-betingelser. NOEA - Nordjyllands Erhvervsakademi
Hvad må vi gøre med Area()? public class Circle: Shape{ private int r; //radius - x, y //og color arves public override float Area(){ } public override voidMoveTo(){ } }//end circle Eksempel: public class Shape{ private int x,y; // figurens position private Colour color; //figurens farve //øvrige attributter public virtual void MoveTo(int newX, int newY){ //PRE 0 <= newX <= maxX && 0 <= newY <= maxY, // hvor maxX og maxY angiver vinduets maksimum // POST x'=newX && y'=newY } public virtual float Area(){ //PRE none //POST returnerer figurens areal med 4 decimalers nøjagtighed // beregnet efter en eller anden tilnærmet metode } }//end Shape Hvad må vi gøre med MoveTo()? NOEA - Nordjyllands Erhvervsakademi
Nedarvning- designovervejelser • Lad os antage at vi skal bruge en klasse der kan indeholde en liste af ansatte, hvor det er muligt at tilføje sidst i listen, men ikke midt i – Skal vi arve fra Array, ArrayList eller? • Nej vi skal ikke arve, men bruge delegation • Arv bør ikke bruges blindt for at opnå kodegenbrug - arv er typespecialisering! • Arv skal kunne forsvares logisk som en ”A er-en B” • Kodegenbrug kan i stedet opnås ved at bygge oven på eksisterende klasser. Kaldes også for komposition, delegering, mm. NOEA - Nordjyllands Erhvervsakademi
Nedarvning - abstract • En klasse som indeholder en eller flere metoder som ikke er defineret kaldes abstrakt • En abstrakt klasse bruges kun i forbindelse med arv, og kan ikke instantieres, dvs. der kan ikke oprettes objekter af en abstrakt klasse. • En abstrakt metode skal redefineres i de(n) nedarvede klasse(r). • En abstrakt metode definerer funktionalitet for alle arvinger (men implementerer ikke). • En constructor i en abstrakt klasse bruges kun af arvingernes constructors NOEA - Nordjyllands Erhvervsakademi
Designeksempel:Composite-pattern Composite: Grafisk editor, Tekstbehandling, Køkkenlager mmm. Hvordan ser en Show-metode ud på Shape, Circle og Picture NOEA - Nordjyllands Erhvervsakademi
Typekompatibilitet, polymorfi og dynamisk binding • Et eksempel (Antag at vi har et klassehieraki med en Konto og CheckKonto som arver fra Konto): Konto konto = new Konto(); CheckKonto ckonto = new CheckKonto(); konto = ckonto; // OK, idet ckonto er typekompatibel, på konto-referencen // kan dog kun tilgå medlemmer fra Konto-klassen. • Når eksempelvis metoden konto.tilskrivRente() kaldes, vil det være checkkontoens metode der bliver kaldt – i fald den er erklæret som override og erklæret virtual i basisklassen. (Objektet retter sig efter objektets type – den dynamiske type - i stedet for referencens – den statiske type: polymorfi og dynamisk binding) NOEA - Nordjyllands Erhvervsakademi
C#- Hvornår er objekter ens? public class Customer { . . . public override bool Equals(object obj) { Customer other; if ((obj == null) || (!(obj is Customer))) return false; // helt sikkert ikke ens other = (Customer) obj; // typecast for adgang return this.id == other.id; // ens hvis ens id... } • Klasser bør override Equals-metoden NOEA - Nordjyllands Erhvervsakademi
Opgaver • Løs resten af KontoOpgaven NOEA - Nordjyllands Erhvervsakademi