Vererbung

Werbung
Vererbung
Klassen - Vererbung
Eine Klasse kann von einer Basisklasse
abgeleitet werden
 Die abgeleitete Klasse erbt die
Eigenschaften und Methoden der
Basisklasse

class derivedClass : [modifier] baseClass
{ … };
Klassen - Vererbung


Eine Ableitung einer Klasse repräsentiert eine
IS-A-Relation
Eine Membervariable repräsentiert eine HASA-Relation
class Vogel : public Tier
{…
Fluegel myWings_;
…}

Vogel ist ein Tier und hat Flügel
Zugriffsmodifizierer bei
abgeleiteten Klassen
public: alle Methoden und
Eigenschaften der Basisiklasse mit dort
definierter Sichtbarkeit weitergereicht
 private: Methoden und Eigenschaften
der Basisklasse von außen nicht mehr
aufrufbar
 protected: Weitere abgeleitete Klassen
bekommen den Zugriff auf die
Basisklasse

Zugriffsmodifizierer bei
abgeleiteten Klassen
class A {
public int a_;
}
class B : public A {
public int b_;
}
class E : private B {
private int e_;
}
class C : private A {
private int c_;
}
class F : protected C {
protected int f_;
}
class D : protected A {
protected int d_;
}
class G : public D {
public int g_;
}
Vererbung – Konstruktoren



Konstruktor der Basisklasse wird vom Konstruktor
der abgeleiteten Klasse aufgerufen
Implizit -> Standardkonstruktor
Explizit mit Parameterübergabe
class derivedClass : baseClass
{ … };
derivedClass::derivedClass(int p1, int p2) :
baseClass(p3)
{ … };
Aufgabe 15: Erben

Erstelle eine Klasse mit folgenden Eigenschaften
 speichert einen Integer-Wert
 besitzt einen Konstruktor, einen Destruktor und eine
Funktion zum Ausgeben des Wertes
 Konstruktor und Destruktor sollen eine Meldungszeile
ausgeben


Erstelle eine davon abgeleitete Klasse, die zusätzlich
einen, ebenfalls über den Konstruktor zu setzenden
Fließkommawert speichert
Erstelle eine Variable von der abgeleiteten und eine
Variable der Basis-Klasse und rufe die in der
Basisklasse definierte Funktion zum Ausgeben des
Wertes auf
Vererbung - Overriding
genau äquivalente Deklaration einer
Funktion / Eigenschaft in einer
abgeleiteten Klasse
 ursprüngliche Deklaration in der
Basisklasse wird versteckt

Aufgabe 16: Erben überschreiben

Ändere die in Aufgabe 15 erstellte
abgeleitete Klasse dahin gehend ab,
dass die geerbte Funktion zum
Anzeigen des Wertes überschrieben
wird
 die überschriebene Funktion soll den in der
abgeleiteten Klasse gespeicherten Wert
ausgeben
Vererbung - Overriding
Aufruf der versteckten Eigenschaft /
Funktion möglich
 in der Memberfunktion der abgeleiteten
Klasse mittels Scope-Operator

 baseClass::Funktion();

Aufruf von Außen: upcast zur
Basisklasse
 ((baseClass)varDerived).Funktion();
Aufgabe 17: versteckte
Wiederentdecken
Ergänze die Anzeigefunktion der
abgeleiteten Klasse so, dass die
Anzeigefunktion der Basisklasse
aufgerufen wird.
 Rufe im Hauptprogramm die
Anzeigefunktion der Basisklasse auf
einer Variablen der abgeleiteten Klasse
auf.

Static vs. Dynamic Binding
beim Linken werden alle Namen
(Variable und Funktionen) durch
Adressen ersetzt
 beim Übersetzen ist nicht immer
bekannt, welche Funktion aufgerufen
werden soll

Static vs. Dynamic Binding
class base {
public void Show();
}
class A : public base {
public void Show();
}
void Display(base &object)
{ object.Show(); }
A myA;
Display(myA);
class B : public base {
public void Show();
}
Static vs. Dynamic Binding:
Virtuell

Schlüsselwort virtual zur Kennzeichnung
dynamischer Bindungen
public virtual void Show();



Objekte besitzen zur Laufzeit einen virtual
table mit den aktuellen Adressen virtueller
Funktionen
Adressen werden beim Konstruktoraufruf in
die Tabelle eingefügt
jede Methode, die eine virtuelle Methode
überschreibt ist ebenfalls virtuell
Abstrakte Methoden

ähnlich virtuellen Methoden, jedoch wird
in der Basisklasse keine
Implementierung vorgenommen
 abgeleitete Klassen müssen die abstrakte
Methode der Basisklasse implementieren
 von Klassen mit abstrakten Methoden kann
keine Instanz erstellt werden
public virtual void Show() = 0;
Aufgabe 18: Virtuell abstrakt





Erstelle eine Klasse 'base', die eine Methode 'show'
besitzt, welche anzeigt, dass sie aufgerufen wurde
Erstelle zwei Klassen 'A' und 'B', welche von 'Base'
abgeleitet wurden und die gleiche Funktionalität wie
'Base' besitzen
Erstelle eine Funktion 'Display', die als Parameter
die Referenz auf eine Variable vom Typ 'Base'
erwartet und auf diese die Methode 'show' aufruft.
Stelle sicher, dass die Methode 'show' der
aufrufenden Variable benutzt wird.
Erstelle je eine Instanz der erstellten Klassen und
übergib diese an die Funktion 'Display'
mache aus der virtuellen Methode 'show' der Klasse
'Base' eine abstrakte Methode
Klassen und Pointer
dynamisches Erzeugen der Objekte
 Klasse1 *VarName = new Klasse2;
 Klasse2 muss entweder (auch über
mehrere Ebenen) von Klasse 1
abgeleitet sein oder gleich Klasse 1

 jede Klasse muss einen virtuellen
Destruktor besitzen, da sonst immer der
Destruktor von Klasse1 aufgerufen wird.
Aufgabe 19: Klassen und Pointer





Verwende die in Aufgabe 18 erstellten
Klassen 'Base', 'A' und 'B' nun mit Pointern
Ändere die Funktion 'Display' so ab, dass
sie einen Pointer auf die Klasse 'Base'
entgegennimmt
Erstelle einen Vektor, der 3 Elemente der
Klasse 'Base' aufnehmen kann
Fülle den Vektor mit je einem Objekt der
oben aufgeführten Klassen
Rufe für jedes Element des Vektors die
Funktion 'Display' auf
Templates – Function Templates
Funktionen mit dynamischen
Parametertypen
 Typ des Parameters wird mit einem
generischen Namen ersetzt
 Tatsächlich verwendeter Typ von
Aufrufparametern abhängig

template <class X, class Y ...>
FunctionName(X var1, Y var2, ...)
{ ... }
Templates – Function Templates
konkrete Festlegung des tatsächlichen
Datentyps beim Funktionsaufruf
 alle mit dem generischen Datentyp
durchgeführten Operationen müssen mit
dem tatsächlichen Datentyp
durchführbar sein
 Aufruf eines Function Templates
unterscheidet sich nicht vom Aufruf einer
normalen Funktion

Function Templates – hinter den
Kulissen





Compiler identifiziert beim Funktionsaufruf
die generischen Teile
Aufrufparameter werden mit den
generischen Teilen verglichen
Ersetzen des generischen durch den
tatsächlichen Typ im Funktionsrumpf
Resultierende Funktion wird vom Compiler
übersetzt
Aufruf der nun erstellten Funktion wird an
der Aufrufstelle eingesetzt
Function Templates
Definition der Template-Funktion muss
(vorerst) im Header geschehen
 Namen des generischen Parameters
möglichst sprechend gestalten
 Rückgabewert ebenfalls als generischer
Typ möglich
 Overloading mit konkreten
Implementierungen ist möglich

Aufgabe 20: Template Max
erstelle eine Templatefunktion, die ein
Array und dessen Länge als generische
Parameter übernimmt und als Ergebnis
den Index des Elementes mit dem
größten Wert zurückgibt (bei mehreren,
das erste Vorkommen)
 Teste diese Funktion, indem du sie mit
einem int32-Array, einem double-Array
und einem char-Array aufrufst

Template Klassen



äquivalent zu Template-Funktionen
beim Erzeugen von Instanzen muss der Typ
angegeben werden
Memberfunktionen müssen in der Headerdatei
deklariert werden (oder per #include direkt
nach der Klassendeklaration eingebunden)
TemplateClass<Typ> var;
template <class theType>
returnType ClassName<theType>::functName
(...)
Herunterladen