180 likes | 435 Views
Arv. Arv. Vad är arv? Arv handlar om att klassificera d.v.s. att ange relationer mellan klasser och inte relationer mellan objekt. Arv gör det möjligt att skapa nya klasser utifrån befintliga, vilket är ett sätt att återanvända gammal kod.
E N D
Arv • Vad är arv? • Arv handlar om att klassificera d.v.s. att ange relationer mellan klasser och inte relationer mellan objekt. • Arv gör det möjligt att skapa nya klasser utifrån befintliga, vilket är ett sätt att återanvända gammal kod. • Arv är en grundläggande teknik för att organisera och skapa klasser.
A B C Terminologi • Basklass • Klassen som redan är definierad och som man vill ärva ifrån • Härledd klass • Klassen som ärver ifrån basklassen • Kan även vara en basklass till andra klasser som ärver ifrån den. • Arv • Är mekanismen för denna teknik • UML Basklass Härledd klass Härledd klass
Person Student Anställd Kund Lärare Chef Säljare Arv • När? • Härledd klass ska representera något som är en sort av det basklassen representerar • Inte för att återanvända koden Adress
Sedd som datatyp Sedd somklass Sedd som mängder class Djur { protected String namn; protected double vikt; public void ät() { /* ... */ } public void sov() { /* ... */ } } class Fågel : Djur { private double vingspann; public void flyg() { /* ... */ } } class Fisk : Djur { private double maxdjup; public void simma() { /* ... */ } } Tre olika sett att se på arv
Arv • En klass kan ärva från högst en klass. • En basklass får ha godtyckligt antal härledda klasser. • Härledd klass kan alltså lägga till och omdefiniera, men inte ta bort. • Det är grundprincip i objektorienterat arv att ett objekt av härledd klass har allt och kan allt som basklassobjekt har och kan. Det är ett slags objekt av basklassen. Men det kanske gör på ett annat sätt. • Arv fungerar helt logiskt i hur många generationer som helst. Varje härledd klass är som om den innehöll allt den ärvde från sin basklass, och den utgör i sin tur utan problem basklass för ytterliggare härledda klasser.
Object Person Adress Student Anställd Kund Lärare Chef Säljare Arv • Klassen System.Object är grundläggande för alla klasser. Med andra ord är alla klasser implicit härledda från klassen System.Object.
Åtkomst • Härledda klasser • Medlemmar i den här klassen kan komma åt icke privata medlemmar definierade i basklassen • Publika data medlemmar i basklassen blir publika även i härledda klassen • Protected data medlemmar i basklassen blir protected även i härledda klassen • protected • Mellanliggande skyddsnivå (public - private) • Kan användas endast av basklassen och alla andra klasser som ärver från basklassen.
Nack- och fördelar med protected • Nackdelar med protected • Härledda klassen behöver inte använda egenskaper (set, get) för att ändra värden av protected data medlemmar (direkt åtkomst) • Metoder i härledda klassen måste skrivas så att de beror av basklassens implementeringen (ändringar i basklassen medför ändringar i alla härledda klasser) • x ändrar namn till xCoordinate • Fördelar med protected • Protected data medlemmar förbättrar prestanda • Onödiga anrop till set och get behövs inte
Att rekommendera • Deklarera basklassens data medlemmar som private • Använd publika egenskaper och metoder så att härledda klassen kan komma åt data medlemmar i basklassen • Anropa basklassens konstruktorn explicit i härledda klassen för att initiera variabler för basklassens objekt.
Exempel class Shape {privateint x, y; public Shape() // tom-konstruktorn{} public Shape(int x, int y) // konstruktorn{this.x = x;this.y = y;} publicdouble Area() // beräkna area{return 0.0;} }
Exempel • I C# är det teknet ”:” för att låta en klass ärva från en annan class Circle : Shape {privateint radius; public Circle() // konstruktorn{} publicdouble Area() // beräkan area{return System.Math.PI * radius * radius;} }
Konstruktorer • Konstruktorer ärvs inte. • Konstruktor i härledda klasser har ett beteende att anropa närmaste basklass konstruktorn. • När objektet av härledda klassen skapas, en kedja av konstruktoranrop påbörjas • Härleda klassens konstruktorn anropar basklassens konstruktorn implicit, eller explicit • Basklassens konstruktor exekveras först
base vid anrop av konstruktor • I en konstruktor kan man anropa en konstruktor för den omedelbara basklassen (base) i en s.k. “initieringslista”. class Circle : Shape { int radius; public Circle (int x, int y, int radius) : base(x,y) { this.radius = radius; } public Circle (int radius) : base(0, 0) { this.radius = radius; } } class Shape { int x,y; public Shape (int x, int y) { this.x = x; this.y = y; } }
base vid anrop av basklassens metoder • Andra metoder i basklassen än konstruktorn kan anropas var som helst inom en metod. För att nå överskuggade metoder i basklassen använder man base. class B : A { int b; public int f() { int x = base.f(); return x + b; } } class A { int a; public int f() { return a; } }
Destruktorer • När Garbage Collector tar bort härledda klassens objekt från minne, GB anropar då klassens destruktorn och en kedja av anrop påbörjas • GB anropar härledda klassens destuktorn • Härledda klassens destruktor exekverar först, och när den exekverat anropar den närmaste basklass destruktor. • Sist anropas Object-klassens destruktorn. • Oavsett om man skriver destruktor eller inte, så kommer eventuell destruktor i basklassen att anropas. • I klasser där Dispose implementeras bör Dispose metoden anropa basklassens Dispose om sådan finns. • Viktigt! Destruktorer anropas aldrig explicit.
Arv kontra aggregering • Arv ska endast användas när det logiska förhållandet mellan befintlig och ny klass verkligen är av den karaktären. • Arv ska endast användas vid solklara fall • Kom ihåg : en sorts • Vid tvekan använd aggregering • Befintliga klassens logik återanvänds genom att ett objekt utgör medlem • Ställ frågan ”är detta verkligen en sorts av basklassen?”. • Om svaret är solkart ja använd arv • Osäker använd aggregering
Class Cylinder : Circle { int height; // metoder för volym etc. } Class Circle { int x, y; int radius; // diverse medlemmar } Class Cylinder { int height; Circle myCircle; public Cylinder(Circle myCircle, int height) { this.height = height; this.myCircle = myCircle; } } Arv kontra aggregering Arv • Exempel: • Är en cylinder en slags cirkel? Eller kanske en cirkel en slags cylinder? Eller kanske är en cylinder ett specialfall av cirkel? Eller .. • Det intressanta här är att en cylinder kan implementeras m.h.a. en cirkel, så koden ser anständig ut. Men logiken är fel. Aggregering