-
Notifications
You must be signed in to change notification settings - Fork 0
06 Vererbung
Vererbung ermöglicht es, eine neue Klasse (Subklasse) von einer bestehenden Klasse (Superklasse) abzuleiten, wobei die Subklasse die Attribute und Methoden der Superklasse erbt. Dies fördert die Wiederverwendung von Code und ermöglicht die Erweiterung bestehender Klassen.
Beispiel:
-
Klasse Person: Enthält Attribute wie
nameundagesowie Methoden wiegetName(),setAge(),print(). -
Klasse Student (abgeleitet von
Person): Erbt die Attribute und Methoden der KlassePersonund fügt neue Attribute (number) und Methoden (setNumber(),printNumber()) hinzu.
- Der Konstruktor einer abgeleiteten Klasse ruft den Konstruktor der Basisklasse auf, um vererbte Attribute zu initialisieren.
- Konstruktoren können in der Initialisierungsliste explizit aufgerufen werden. Wenn dies nicht geschieht, wird der Standardkonstruktor der Basisklasse verwendet.
- Der Destruktor einer abgeleiteten Klasse ruft nach Abschluss seines eigenen Codes automatisch den Destruktor der Basisklasse auf.
Beispiel:
class Student : public Person {
int m_number;
public:
Student(const std::string& name, int age, int nr) : Person(name, age), m_number(nr) {}
};- Up-Cast: Implizite Konvertierung von einem Zeiger auf eine abgeleitete Klasse zu einem Zeiger auf die Basisklasse. Dies ist immer sicher.
Person* pPers = new Student("Anna", 21, 50101); // Impliziter Up-Cast-
Down-Cast: Explizite Konvertierung von einem Zeiger auf die Basisklasse zu
einem Zeiger auf die abgeleitete Klasse. Dies ist nur dann sicher, wenn das
Objekt tatsächlich vom Zieltyp ist. Dafür wird
dynamic_castverwendet.
Student* pStud = dynamic_cast<Student*>(pPers); // Gültiger Down-CastRTTI ermöglicht es, zur Laufzeit den genauen Typ eines Objekts zu bestimmen. Der
Operator typeid und der dynamic_cast-Operator sind zentrale Elemente von
RTTI.
Beispiel:
Person* p = new Student();
if (typeid(*p) == typeid(Student)) {
std::cout << "Das Objekt ist vom Typ Student." << std::endl;
}- Verdecken: Abgeleitete Klassen können Attribute oder Methoden mit demselben Namen wie die der Basisklasse haben, was das Attribut der Basisklasse verdeckt. Dies sollte möglichst vermieden werden.
- Überschreiben (Overriding): Abgeleitete Klassen können Methoden der Basisklasse überschreiben, indem sie dieselbe Signatur verwenden. Dadurch kann das Verhalten der Methode an die Anforderungen der abgeleiteten Klasse angepasst werden.
Beispiel:
class Person {
public:
virtual void print() const { std::cout << "Person" << std::endl; }
};
class Student : public Person {
public:
void print() const override { std::cout << "Student" << std::endl; }
};Polymorphie ermöglicht es, dass eine Methode unterschiedliche Implementierungen
aufrufen kann, abhängig davon, welches Objekt zur Laufzeit verwendet wird. Dafür
müssen Methoden in der Basisklasse als virtual deklariert werden.
Beispiel:
Person* p = new Student();
p->print(); // Ruft die Methode Student::print() auf- Eine Klasse kann mithilfe des Schlüsselworts
finalals nicht vererbbar markiert werden.
class C final : B { ... }; // Klasse C kann nicht weiter abgeleitet werden- Eine Methode kann ebenfalls mit
finalmarkiert werden, um das Überschreiben in abgeleiteten Klassen zu verhindern.
virtual void f() final;In C++ ist Mehrfachvererbung möglich, was bedeutet, dass eine Klasse von mehreren Basisklassen erben kann. Dies führt jedoch oft zu Problemen wie Mehrdeutigkeiten, weshalb sie hauptsächlich für die Implementierung von Interfaces genutzt wird.
Beispiel:
class A { ... };
class B { ... };
class C : public A, public B { ... }; // MehrfachvererbungZur Lösung der Probleme der Mehrfachvererbung kann virtuelle Vererbung verwendet werden, um sicherzustellen, dass es nur eine Kopie der Basisklasse gibt.
Beispiel:
class A {
...
};
class B : virtual public A {
...
};
class C : virtual public A {
...
};
class D : public B, public C {
...
};Diese Zusammenfassung bietet einen Überblick über die wichtigsten Konzepte der Vererbung in C++, wie Konstruktoren in abgeleiteten Klassen, Polymorphie, Typkonvertierungen und Mehrfachvererbung. Vererbung ist ein zentraler Bestandteil der objektorientierten Programmierung und ermöglicht die Erweiterung und Wiederverwendung von Code auf effiziente Weise.