Vererbung. Das Prinzip der Vererbung im täglichen Leben:

Slides:



Advertisements
Ähnliche Präsentationen
Objektorientierte Programmierung
Advertisements

der Universität Oldenburg
1 Funktionstemplates Einbinden von Templates: –Eine *.o Datei, die durch Übersetzen einer Datei nur mit Templates erzeugt wurde, enthält keinen Programmcode.
Abstrakte Klassen Basisklassen sollten in der Regel sehr allgemein sein. Oft ist es nicht notwendig, dass Objekte dieser generellen Basisklassen angelegt.
Kritische Betrachtung
Objektorientierte Programmierung mit Java unter BlueJ
Abstrakte Klassen HS Merseburg (FH) WS 06/07.
Java: Objektorientierte Programmierung
Java: Grundlagen der Objektorientierung
Vererbung.
Abstrakte Klassen.
Datentyp- umwandlung. Literale sind: Bezeichner mit einem festen Wert wie z.B:
Klassenvariable (auch Klassendaten bzw. statische Attribute genannt) und statische Methoden.
Dateien. Eine Datei wird in C++ als ein Stream, also als ein Objekt einer bestimmten Klasse dargestellt.
Ein Beispiel in Java.
Erweiterte Zuweisungskompatibilität
Klassenvariable. Da man für jede Kuh bzw. jede Henne auf dem Markt den gleichen Preis für ein Liter Milch, bzw. den gleichen Preis für ein Ei bekommt,
Aufgabe: Erstellen Sie die Klasse Punkt, (mit den entsprechenden Attributen und Methoden), die einen Punkt (Pixel) in einer grafischen zweidimensionalen.
Konstruktoren.
Objekte werden als Adressen (Referenzen) übergeben. Dies führt manchmal zu unerwarteten Ergebnissen...
Polymorphie (Vielgestaltigkeit)
Assoziationen (Beziehungen). Zwischen Objekten kann es eine Beziehung geben.
Polymorphie (Vielgestaltigkeit)
Objekte und Arbeitsspeicher
Interface bzw. Schnittstelle anschaulich: Hüllenklasse
Dynamischer Speicher. In einer Funktion wird z.B. mit der Deklaration int i; Speicher auf dem sogenannten Stack reserviert. Wenn die Funktion verlassen.
Universität Dortmund, Lehrstuhl Informatik 1 EINI II Einführung in die Informatik für Naturwissenschaftler und Ingenieure.
Programmieren mit JAVA
Vererbung Spezialisierung von Klassen in JAVA möglich durch
PRJ 2007/1 Stefan Dissmann Motivation Problem: gleiche Datenstrukturen werden für verschiedene Objekte gebraucht: z.B. Listen von Studierenden, Kunden,
PKJ 2005/1 Stefan Dissmann Ausblick Es fehlen noch: Möglichkeiten zum Strukturieren größerer Programme Umgang mit variabler Zahl von Elementen Umgang mit.
PKJ 2005/1 Stefan Dissmann Zusammenfassung Bisher im Kurs erarbeitete Konzepte(1): Umgang mit einfachen Datentypen Umgang mit Feldern Umgang mit Referenzen.
Zusammenfassung Vorwoche
Abstrakter Datentyp in C++ I - Klasse -
C++ Vererbung und Polymorphie
07-GraphischeObjekte Graphische Objekte in EMMA301Paint.
DVG Klassen und Objekte
Seite 1 Interface - Konzept Ein Interface führt einen neuen Datentyp ein: interface Frau {... } Das Interface enthält Deklarationen ( keine Definitionen.
PRJ 2007/1 Stefan Dissmann Verkettete datenstruktur: Liste Problem: Liste, die eine beliebige Zahl von Elementen verwaltet Operationen: Erzeugen, Anfügen,
Informatik 1 Übung 8. NACHBESPRECHUNG Übung 8 Rekursion Existiert Weg von A nach B?
Klassendefinitionen in Java
Copyright 2011 Bernd Brügge, Christian Herzog Grundlagen der Programmierung TUM Wintersemester 2011/12 Kapitel 11, Folie 1 2 Dr. Christian Herzog Technische.
Einführung in die Programmierung Wintersemester 2008/09 Prof. Dr. Günter Rudolph Lehrstuhl für Algorithm Engineering Fakultät für Informatik TU Dortmund.
Einführung in die Programmierung Wintersemester 2008/09 Prof. Dr. Günter Rudolph Lehrstuhl für Algorithm Engineering Fakultät für Informatik TU Dortmund.
Einführung in die Informatik für Naturwissenschaftler und Ingenieure
Einführung in die Informatik für Naturwissenschaftler und Ingenieure (alias Einführung in die Programmierung) (Vorlesung) Prof. Dr. Günter Rudolph Fachbereich.
Einführung in die Informatik für Naturwissenschaftler und Ingenieure (alias Einführung in die Programmierung) (Vorlesung) Prof. Dr. Günter Rudolph Fachbereich.
Einführung in die Programmierung Wintersemester 2011/12 Prof. Dr. Günter Rudolph Lehrstuhl für Algorithm Engineering Fakultät für Informatik TU Dortmund.
Javakurs FSS 2012 Lehrstuhl Stuckenschmidt
OOP-Begriffe Abstraktion Modellieren Klasse Objekt Attribute Methoden
Informatik Zustandsorientiertes Modellieren und Programmieren 2.4 Datenkapselung 2.4 Datenkapselung Objekte können miteinander kommunizieren, indem.
2. Zustandsorientiertes Modellieren 2.4 Datenkapselung
Polymorphie (Vielgestaltigkeit). Wenn eine Methode, wie z.B. print für verschiedene Programmteile steht (und z.B. einmal Objekte verschiedener Klassen.
early binding (frühe Bindung) late binding (späte Bindung)
Erweiterte Zuweisungskompatibilität. Wie kann man Objekte verschiedener Klassen einer Klassenhierarchie einander zuweisen ?
Funktionen. Aufgabe : Eingabe zweier Zahlen ---> Minimum bestimmen Dann nochmals Eingabe zweier Zahlen ---> Minimum bestimmen.
Pointer. Grundsätzliches: Im Arbeitsspeicher werden Daten gespeichert. Um auf die Daten eindeutig zugreifen zu können, werden diesen Daten Adressen zugeordnet.
Funktionen, Felder und Parameter- übergabe. Funktionsaufruf mit Feld als Parameter: Parameter = Name des Feldes.
Vererbung. Klassen - Vererbung  Eine Klasse kann von einer Basisklasse abgeleitet werden  Die abgeleitete Klasse erbt die Eigenschaften und Methoden.
Tutorium Software-Engineering SS14 Florian Manghofer.
Tutorium Software-Engineering SS14 Florian Manghofer.
C++ FÜR cOMPUTERSPIELENTWICKLER
Tutorium Software-Engineering SS14 Florian Manghofer.
Vererbung in Java. public abstract class Form { protected int breite; protected int hoehe; protected String farbe; /** * Erzeuge eine Form der Breite.
Konstruktoren.
Vererbung.
Es gibt Klassen, die mit der Entwicklungsumgebung ausgeliefert werden
2. Vererbung und Kapselung
Definition Felder Konstruktor Methoden Beispiel
Implementieren von Klassen
 Präsentation transkript:

Vererbung

Das Prinzip der Vererbung im täglichen Leben:

Walter besitzt ein Haus.

Walter erbt nun 10000Euro. Also besitzt er insgesamt:

In C++: ErblasserErbe ---> Basisklasse ---> abgeleitete Klasse In C++ darf man einen Erben (abgeleitete Klasse) selbst basteln

Statt Basisklasse sagt man auch: Oberklasse, Vaterklasse

Statt abgeleiteter Klasse sagt man auch: Unterklasse, Sohnklasse, Subklasse

Eine abgeleitete Klasse wird in C++ wie folgt angegeben: class Ei:public Huhn{... } Basisklasse abgeleitete Klasse wird getrennt durch Doppelpunkt Zugriffsart

Die abgeleitete Klasse (kurz: Ableitung) besitzt automatisch alle Member (Ausnahme: Konstruktor) der Basisklasse.

Beispiel:

Von einem Flachdachhaus wird ein Modell (Draufsicht) erstellt:

Der Einfachheit halber wird nur die Grundfläche (ohne Zimmer, usw.) des Hauses abgebildet. Aufgabe: Realsieren Sie die Klasse Modell in C++.

class Modell{ private: double l; double b; public: Modell(double ll, double bb); void setL(double ll); void setB(double bb); double getL(); double getB(); double getFlaeche(); }

Modell::Modell(double ll, double bb){ l = ll; b = bb; } void Modell::setL(double ll){ l = ll; } void Modell::setB(double bb){ b = bb; }

double Modell::getL(){ return(l); } double Modell::getB(){ return(b); } double Modell::getFlaeche(){ return(l*b); }

Jetzt soll ein genaueres Modell des Flachdachhauses erstellt werden: Modell aus Styropor (oder Ton). Aufgabe: Realsieren Sie in C++ die Klasse Gmodell.

Wie kann man sich dabei Schreibarbeit sparen ? Wie kann man Softwareteile dabei wiederverwenden ? Indem man die Vererbung benutzt.

Welche Member der Klasse Modell kann man übernehmen (erben) ? Welche Member kommen neu dazu ?

class Modell{ private: double l; double b; public: Modell(double ll, double bb); void setL(double ll); void setB(double bb); double getL(); double getB(); double getFlaeche(); } Alle außer dem Konstruktor Welche Member werden vererbt ? Welche Member müssen neu dazu ?

double h; double getVolumen(); Die reliefförmig dargestellten Member werden geerbt. Die rot dargestellten Member kommen neu dazu. Wie wird eine Vererbung erreicht ? :public Modell void setH(double hh); double getH(); Gmodell(double ll, double bb, double hh);

Also sieht die Klasse folgendermassen aus:

class Gmodell:public Modell{ private: double h; public: Gmodell(double ll, double bb, double hh); void setH(double hh); double getH(); double getVolumen(); } Die Methoden müssen noch außerhalb der Klassen implementiert werden.

Realisieren Sie die Methoden in C++

void Gmodell::setH(double hh){ h = hh; } double Gmodell::getH(){ return(h); } double Gmodell::getVolumen(){ return(getFlaeche()*h); } Diese Methode wird von der Klasse Modell vererbt.

double Gmodell::getVolumen(){ return(b*l*h); } Warum ist diese Lösung falsch ? Es gibt Probleme mit dem Zugriffschutz (l und b sind private). Näheres dazu siehe später.

Gmodell::Gmodell(double ll, double bb, double hh): Modell(ll,bb){ setH(hh); } Da die Klasse Gmodell von der Klasse Modell erbt, muß beim Anlegen eines Objekts der Klasse Gmodell auch der Konstruktor der Klasse Modell aufgerufen werden. Wird dies nicht gemacht, dann wird automatisch (ohne Zutun des Programmierers) der Standardkonstruktor der Klasse Modell aufgerufen. Was passiert, wenn der Standardkonstruktor nicht existiert ? Dann wird dieser automatisch vom Compiler angelegt, außer.... es gibt einen Konstruktor mit (1, 2, 3,...) Parametern. Dann liefert der Compiler eine Fehlermeldung.

Beispiel für die Benutzung der o.g. Klassen in einem Hauptprogramm:

int main(){ Modell m(10,20); Gmodell g(2,3,4); double a,b,c, f, v; a = m.getL(); b = m.getB(); c = m.getH(); f = m.getFlaeche(); v = m.getVolumen(); a = g.getL(); b = g.getB(); c = g.getH(); f = g.getFlaeche(); v = g.getVolumen(); return 0; } // a=10 // b=20 // syntaktisch falsch // f=200 // a=2 // b=3 // c=4 // f=6 // v=24 // synt. falsch

Verdeckte Member

class Gmodell:public Modell{ private: double h; public: Gmodell(double ll, double bb, double hh); void setH(double hh); double getH(); double getVolumen(); double getFlaeche(); } Alles gleich wie vorher außer, daß eine Methode gleichen Namens wie in der Basisklasse existiert, die die Oberfläche des Modells (Quaders) berechnet. Wie muss sie implementiert werden ?

double Gmodell::getFlaeche(){ return(2*(getL()*getB()+getL()*h +getB()*h)); } double Gmodell::getFlaeche(){ return(2*(l*b+l*h+b*h)); } Warum ist diese Lösung falsch ? Es gibt Probleme mit dem Zugriffschutz (l und b sind private). Näheres dazu siehe später.

int main(){ Gmodell g(2,3,4); double f; f = g.getFlaeche(); return 0; } // f=6 Es wird auf die Methode der Unterklasse und nicht der Oberklasse zugegriffen, weil die Methode der Oberklasse durch die Methode der Unterklasse verdeckt wird. Mit Angabe der Klasse und des sogenannten Scope Operators :: kann man auf die verdeckten Mitglieder zugreifen. f = g.Modell::getFlaeche(); // f=52 Von welcher Klasse wird diese Methode aufgerufen ?

Darstellung der Vererbung durch UML

Basisklasse... Subklasse... Attribute Methoden Attribute Methoden Pfeil bedeutet: erbt von Analog zum Zugriffsschutz +und - bedeutet # : Methode ist protected

Aufgabe: Stellen Sie die Klassen Modell, Gmodell und ihre Vererbungshierarchie in UML dar.

Modell - l: double - b: double + Modell(double ll, double bb) + setL(double ll): void + setB(double bb): void + getL():double + getB():double + getFlaeche():double Gmodell - h: double + Gmodell(double ll, double bb, double hh) + setH(double hh): void + getH():double + getVolumen():double Statt dem Zugriffschutz + oder - kann auch der Zugriffschutz # (siehe später) benutzt werden.

Zugriffschutz (Zugriffsberechtigung) bei Klassen

Bedeutung der Zugriffsarten:

Zugriff innerhalb einer Klasse bedeutet den Zugriff auf ein Member von innerhalb einer Methode der Klasse. Beispiel: void Modell::setL(double ll){ l = ll; } Zugriff auf das Member setL

Zugriff außerhalb einer Klasse bedeutet den Zugriff auf ein Member von einem Objekt mit Hilfe des Punkts. Beispiel: int main{ Modell m(2,8); m.setL(5); return 0; } Zugriff auf das Member setL

Zugriffschutz (Zugriffsberechtigung) bei Klassen ohne Vererbung

Beispiel:

class Waisenkind{ private: int priWK; protected: int proWK; public: int pubWK; void f_WK(){ priWK=1; proWK; pubWK=3; } }; int main(){ Waisenkind myWK; myWK.f_WK(); myWK.priWK=10; myWK.proWK=11; myWK.pubWK=12; return 0; } Wo sind die Zugriffe ? Sind diese außerhalb/innerhalb ? Sind sie möglich ? Zugriff außerhalb, möglich Zugriff innerhalb, möglich Zugriff außerhalb, unmöglich Zugriff außerhalb, möglich

class Waisenkind{ private: int priWK; protected: int proWK; public: int pubWK; void f_WK(){ priWK=1; proWK; pubWK=3; } }; int main(){ Waisenkind myWK; myWK.f_WK(); myWK.priWK=10; myWK.proWK=11; myWK.pubWK=12; return 0; } Welche Regel läßt sich daraus ableiten ? Zugriff innerhalb ist auf private, protected und public Member möglich. Zugriff außerhalb ist nur auf public Member möglich.

Zugriffschutz (Zugriffsberechtigung) bei Klassen mit Vererbung

Auf die nicht vererbten Member einer Klasse gilt die gleiche Regel wie vorher: Zugriff innerhalb ist auf private, protected und public Member möglich. Zugriff außerhalb ist nur auf public Member möglich.

Das Problem ist nur: Wie ist der Zugriffschutz (Zugriffsberechtigung) auf die vererbten Member einer Klasse geregelt ?

Zugriff auf die vererbten Member einer Klasse:

Aus Platzgründen muss im Folgenden auf die Trennung von Deklaration und Implementierung der Methoden verzichtet werden.

Beispiel:

class Mutter{ private: int priM; protected: int proM; public: int pubM; }; Zugriffsmanipulation der Member in der Basisklasse und...

class Kind1:private Mutter{ private: void prifK(){ priM=11; proM=12; pubM=13; } protected: void profK(){ priM=14; proM=15; pubM=16; } public: void pubfK(){ priM=17; proM=18; pubM=19; } };... Zugriffsmanipulation (der gesamten Basisklasse) bei der Vererbung der Klasse bestimmen die Zugriffsberechtigung: Sind die Zugriffe auf die rotgedruckten Member in der Basisklasse möglich ? protected public

Insgesamt bestimmen also die "Schalter" Zugriffsmanipulation der Basisklasse und Zugriffsmanipulation der Member der Basisklasse die resultierende Zugriffsberechtigung.

private-Member: Zugriff nur von innerhalb der Klasse möglich protected -Member: Zugriff von innerhalb der Klasse möglich Zugriff von innerhalb einer abgeleiteten Klasse möglich public -Member : Zugriff von innerhalb der Klasse möglich Zugriff von innerhalb einer abgeleiteten Klasse möglich Zugriff von außerhalb einer Klasse aus möglich

int main(){ Kind1 k1; k1.prifK(); k1.profK(); k1.pubfK(); k1.priM=105; k1.proM=109; k1.pubM=113; return 0; } Bei welchen Anweisungen oben können Sie jetzt schon entscheiden, ob die Zugriffe erlaubt sind oder nicht ? Bei welchen können Sie noch nicht entscheiden ? Um welche Zugriffe handelt es sich (innerhalb / außerhalb) ? Zugriff von außerhalb auf ein nicht vererbtes private Member: nicht erlaubt Zugriff von außerhalb auf ein nicht vererbtes protected Member: nicht erlaubt Zugriff von außerhalb auf ein nicht vererbtes public Member: erlaubt Die restlichen Zugriffe von außerhalb betreffen vererbte Member: bis jetzt noch nicht entscheidbar, muss noch geregelt werden...

privateprotectedpublic private kein Zugriff protectedprivateprotected publicprivateprotectedpublic Zugriffsberechtigung von der abgeleiteten Klasse auf die vererbten Member der Basisklasse : Man sieht: Die Zugriffsberechtigung der Basisklasse kann durch die Klassenspezifikation vermindert, aber nicht vergrößert werden. Member in Basisklasse Vererbung Basisklasse

Sinn: Member von Klassen, die z.B. für die Gestaltung einer grafischen Oberfläche vom System zur Verfügung gestellt werden, sollen nicht durch eine Vererbung, die ein Programmierer realisiert, vergrößert werden können.

Für die resultierende Zugriffsberechtigung für die vererbten Member gilt die gleiche Regel wie vorher:

Zugriff innerhalb ist auf private, protected und public Member möglich. Zugriff außerhalb ist nur auf public Member möglich. Wobei private, protected und public aus der vorigen Tabelle ermittelt werden müssen !!

Damit gilt dann für den Zugriff von der abgeleiteten Klasse aus:

privateprotectedpublic private--- protected+++ public+++ + bedeutet: Zugriff möglich - bedeutet: Kein Zugriff möglich (Compiler) Member in Basisklasse Vererbung Basisklasse

Damit gilt dann für den Zugriff von außerhalb:

privateprotectedpublic private--- protected--- public--+ Member in Basisklasse Vererbung Basisklasse

Gesamtergebnis: R1) Zugriff auf ein vererbtes Member: a) Regel anwenden R2) Zugriff auf ein nicht vererbtes Member: a) Resultierende Zugriffsberechtigung aus Tabelle ermitteln b) Regel anwenden

Zurück zur vorigen Aufgabe. Welche Zugriffe sind möglich und warum ? (kein Zugriff bedeutet: Fehlermeldung des Compilers)

class Mutter{ private: int priM; protected: int proM; public: int pubM; };

class Kind1:private Mutter{ private: void prifK(){ priM=11; proM=12; pubM=13; } protected: void profK(){ priM=14; proM=15; pubM=16; } public: void pubfK(){ priM=17; proM=18; pubM=19; } }; private + private = kein Zugriff (R2) protected + private = private (R2) public + private = private (R2) private + private = kein Zugriff (R2) protected + private = private (R2) public + private = private (R2) private + private = kein Zugriff (R2) protected + private = private (R2) public + private = private (R2)

int main(){ Kind1 k1; k1.prifK(); k1.profK(); k1.pubfK(); k1.priM=105; k1.proM=109; k1.pubM=113; return 0; } Voraussetzungen: In der letzten Folie werden die Anweisungen, die keinen Zugriff verursachen und eine Compilermeldung bringen, entfernt. no: private (R1) no: protected (R1) yes: public (R1) no bedeutet : kein Zugriff möglich yes bedeutet : Zugriff möglich no: private + private = kein Zugriff (R2) no: protected + private = private (R2) no: public + private = private (R2)

Der Klassenzugriffschutz wird von private auf protected geändert. Was passiert ?

class Kind2:private Mutter{ private: void prifK(){ priM=11; proM=12; pubM=13; } protected: void profK(){ priM=14; proM=15; pubM=16; } public: void pubfK(){ priM=17; proM=18; pubM=19; } };

class Kind2: Mutter{ private: void prifK(){ priM=11; proM=12; pubM=13; } protected: void profK(){ priM=14; proM=15; pubM=16; } public: void pubfK(){ priM=17; proM=18; pubM=19; } };

class Kind2: Mutter{ private: void prifK(){ priM=11; proM=12; pubM=13; } protected: void profk(){ priM=14; proM=15; pubM=16; } public: void pubfK(){ priM=17; proM=18; pubM=19; } }; protected private + protected = kein Zugriff (R2) protected + protected = protected (R2) public + protected = protected (R2) private + protected = kein Zugriff (R2) protected + protected = protected (R2) public + protected = protected (R2) private + protected = kein Zugriff (R2) protected + protected = protected (R2) public + protected = protected (R2)

int main(){ Kind2 k2; k2.prifK(); k2.profK(); k2.pubfK(); k2.priM=105; k2.proM=109; k2.pubM=113; return 0; } Voraussetzungen: In der letzten Folie werden die Anweisungen, die keinen Zugriff verursachen und eine Compilermeldung bringen, entfernt. no: private (R1) no: protected (R1) yes: public (R1) no: private + protected = kein Zugriff (R2) no bedeutet : kein Zugriff möglich yes bedeutet : Zugriff möglich no: protected + protected = protected (R2) no: public + protected = protected (R2)

Der Klassenzugriffschutz wird von protected auf public geändert. Was passiert ?

class Kind3:protected Mutter{ private: void prifK(){ priM=11; proM=12; pubM=13; } protected: void profK(){ priM=14; proM=15; pubM=16; } public: void pubfK(){ priM=17; proM=18; pubM=19; } };

class Kind3: Mutter{ private: void prifK(){ priM=11; proM=12; pubM=13; } protected: void profK(){ priM=14; proM=15; pubM=16; } public: void pubfK(){ priM=17; proM=18; pubM=19; } };

class Kind3: Mutter{ private: void prifK(){ priM=11; proM=12; pubM=13; } protected: void profK(){ priM=14; proM=15; pubM=16; } public: void pubfk(){ priM=17; proM=18; pubM=19; } }; public private + public = kein Zugriff (R2) protected + public = protected (R2) public + public = public (R2) private + public = kein Zugriff (R2) protected + public = protected (R2) public + public = public (R2) private + public = kein Zugriff (R2) protected + public = protected (R2) public + public = public (R2)

int main(){ Kind3 k3; k3.prifK(); k3.profK(); k3.pubfK(); k3.priM=105; k3.proM=109; k3.pubM=113; return 0; } Voraussetzungen: In der letzten Folie werden die Anweisungen, die keinen Zugriff verursachen und eine Compilermeldung bringen, entfernt. no: private (R1) no: protected (R1) yes: public (R1) no bedeutet : kein Zugriff möglich yes bedeutet : Zugriff möglich no: private + public = kein Zugriff (R2) no: protected + public = protected (R2) yes: public + public = public (R2)

Konstruktoren, Destruktoren bei der Vererbung

Beispiel:

class BasisKlasse{ public: BasisKlasse(int i); ~BasisKlasse(); }; BasisKlasse::BasisKlasse(int i){ cout << "Aufruf Konstr. BK \n"); }; BasisKlasse::~BasisKlasse(){ cout << "Aufruf Destr. BK \n"); };

class SubKlasse:public BasisKlasse{ public: SubKlasse(int i); ~SubKlasse(); }; SubKlasse::SubKlasse(int i): BasisKlasse(i){ cout << "Aufruf Konstr. SK \n"); }; SubKlasse::~SubKlasse(){ cout << "Aufruf Destr. SK \n"); };

// Welche Ausgaben werden auf dem // Bildschirm erzeugt ? int main(){ SubKlasse s(1); return 0; }

Aufruf Konst. BK Aufruf Konst. SK Aufruf Destr. SK Aufruf Destr. BK Es gilt des weiteren:

Wenn der Konstruktor der Subklasse nicht (weil es der Programmierer vergessen hat zu implementieren) einen Konstruktor der Basisklasse aufruft, dann ruft er automatisch den Standardkonstruktor der Basisklasse auf.

Der Destruktor in der Subklasse ruft automatisch den Destruktor der Basisklasse auf. Wenn der Destruktor der Subklasse nicht implementiert wird, wird er automatisch vom Compiler erzeugt. Dieser automatisch erzeugte Destruktor ruft dann auch den Destruktor der Basisklasse auf.

Wann soll man eine Vererbung sinnvoll einsetzen ?

wenn die folgende Beziehung besteht: Subklasse "ist ein(e)" Basisklasse.

Beispiele der Vererbung: Ein LKW ist ein Fahrzeug Eine Katze ist ein Tier Eine Tulpe ist eine Pflanze abgeleitete Klasse Basisklasse

Der Prozeß, um von einer Basisklasse durch Detaillierung und Konkretiserung zu einer Subklasse zu kommen, nennt man Spezialisierung. Der Prozeß, um von einer Subklasse durch Verallgemeinerung und Abstraktion zur Basisklasse zu kommen, nennt man Generalisierung.