hochkant=1.1|mini|Vererbung dargestellt mittels UML. Die abgeleitete Klasse hat die Attribute x und y und verfügt über die Methoden a und b (im UML-Sprachgebrauch Operationen a und b). Die Vererbung () ist eines der grundlegenden Konzepte der Objektorientierung und hat große Bedeutung in der Softwareentwicklung. Die Vererbung dient dazu, aufbauend auf existierenden Klassen neue zu schaffen, wobei die Beziehung zwischen ursprünglicher und neuer Klasse dauerhaft ist. Eine neue Klasse kann dabei eine Erweiterung oder eine Einschränkung der ursprünglichen Klasse sein. Neben diesem konstruktiven Aspekt dient Vererbung auch der Dokumentation von Ähnlichkeiten zwischen Klassen, was insbesondere in den frühen Phasen des Softwareentwurfs von Bedeutung ist. Auf der Vererbung basierende Klassenhierarchien bzw. VererbungssystemeGeorge A. Miller: Wörter. Streifzüge durch die Psycholinguistik. Herausgegeben und aus dem Amerikanischen übersetzt von Joachim Grabowski und Christiane Fellbaum. Spektrum der Wissenschaft, Heidelberg 1993; Lizenzausgabe: Zweitausendeins, Frankfurt am Main 1995; 2. Auflage ebenda 1996, ISBN 3-86150-115-5, S. 210–217. spiegeln strukturelle und verhaltensbezogene Ähnlichkeiten der Klassen wider.
Die vererbende Klasse wird meist Basisklasse (auch Super-, Ober- oder Elternklasse) genannt, die erbende abgeleitete Klasse (auch Sub-, Unter- oder Kindklasse). Den Vorgang des Erbens nennt man meist Ableitung oder Spezialisierung, die Umkehrung hiervon Generalisierung, was ein vorwiegend auf die Modellebene beschränkter Begriff ist. In der Unified Modeling Language (UML) wird eine Vererbungsbeziehung durch einen Pfeil mit einer dreieckigen Spitze dargestellt, der von der abgeleiteten Klasse zur Basisklasse zeigt. Geerbte Attribute und Methoden werden in der Darstellung der abgeleiteten Klasse nicht wiederholt.
In der Programmiersprache Simula wurde 1967 die Vererbung mit weiteren Konzepten objektorientierter Programmierung erstmals eingeführt.Ole-Johan Dahl, Kristen Nygaard: Class and Subclass Declarations. In: J. N. Buxton (Hrsg.): Simulation Programming Languages. Proceedings of the IFIP working conference on simulation programming languages, Oslo, Mai 1967 North-Holland, Amsterdam, 1968, S. 158–174 (; PDF; 693 kB) Letztere hat seitdem in der Softwareentwicklung wichtige neue Perspektiven eröffnet und auch die komponentenbasierte Entwicklung ermöglicht.
Abgeleitete Klasse und Basisklasse stehen typischerweise in einer „ist-ein“-Beziehung zueinander. Klassen dienen der Spezifikation von Datentyp und Funktionalität, die beide vererbt werden können. Einige Programmiersprachen trennen zumindest teilweise zwischen diesen Aspekten und unterscheiden zwischen Schnittstelle (englisch Interface) und Klasse. Wenn eine abgeleitete Klasse von mehr als einer Basisklasse erbt, wird dies Mehrfachvererbung genannt. Mehrfaches Erben ist nicht bei allen Programmiersprachen möglich, bei manchen nur in eingeschränkter Form.
Beispiel mini|hochkant=2.5|Beispielhaftes Klassendiagramm (UML)
Das folgende Beispiel stellt einen möglichen Ausschnitt aus dem Anwendungsgebiet der Unterstützung eines Fahrzeugverleihs dar. Die Basisklasse Fahrzeug enthält die Attribute Fahrzeugnummer, Leergewicht und ZulässigesGesamtgewicht. Die Spezialisierungen Kraftfahrzeug und Fahrrad ergänzen weitere Attribute zu den von der Basisklasse geerbten Gewichtsangaben und der identifizierenden Fahrzeugnummer. In jedem Objekt der Klasse Kraftfahrzeug werden also die Attribute Fahrzeugnummer, Leergewicht, ZulässigesGesamtgewicht, Höchstgeschwindigkeit und Leistung gespeichert. In der Klasse Fahrzeug gibt es die Methode PruefeVerfuegbarkeit, die unter Verwendung der Fahrzeugnummer die Verfügbarkeit eines bestimmten Fahrzeugs ermittelt, beispielsweise durch einen Datenbankzugriff. Diese Methode wird von allen Spezialisierungen geerbt und ist somit für diese ebenfalls nutzbar. Dasselbe gilt auch dann, wenn nachträglich eine weitere Methode in der Klasse Fahrzeug ergänzt wird, beispielsweise eine Methode HatNavigationssystem, wenn ein Teil der Fahrzeuge mit Navigationssystemen ausgestattet wird.
In der Klasse Kraftfahrzeug wird die Methode PrüfeFahrerlaubnis eingeführt. Diese Methode soll bei Übergabe einer konkreten Fahrerlaubnis ermitteln, ob das durch ein Objekt dieser Klasse repräsentierte Fahrzeug mit dieser Fahrerlaubnis geführt werden darf.Die Modellierung dient hier nur zur Veranschaulichung. Beispielsweise wären Attribute wie Antriebsart, Hubraum und ob ein Anhänger mitgeführt wird in einem realitätsnahen System ebenfalls zu berücksichtigen. Die Fahrerlaubnis könnte länderspezifisch sein, zudem müssen die Länder berücksichtigt werden, in denen das Kraftfahrzeug betrieben werden soll. Auf Basis der Attribute Höchstgeschwindigkeit und Leistung können möglicherweise bereits in der Klasse Kraftfahrzeug einige Implementierungen vorgenommen werden, wenn für alle betreibbaren Fahrzeuge eines Landes die Eignung der Fahrerlaubnis bereits anhand des zulässigen Gesamtgewichts, der Höchstgeschwindigkeit und der Leistung entscheidbar ist. Viele Fälle sind aber erst auf Ebene der Spezialisierungen Motorrad, PKW und LKW entscheidbar, so dass diese Methode in diesen Klassen überschrieben werden muss. Beispielsweise ist die Anzahl der Sitzplätze des Kraftfahrzeugs in manchen Fällen zu berücksichtigen.
mini|links|Schematisches Speicherabbild eines Objekts der Klasse PKW Innerhalb eines dieses Modell implementierenden Anwendungsprogramms würde zur Prüfung, ob eine Fahrerlaubnis gültig ist, nach Eingabe der entsprechenden Fahrzeugdaten das konkrete, zu mietende Fahrzeug instantiiert, das heißt die entsprechende Spezialisierung. Zudem würde ebenfalls ein Objekt für die vorliegende Fahrerlaubnis erzeugt. Dieses würde der Methode PrüfeFahrerlaubnis des Fahrzeug-Objekts übergeben und von dieser ausgewertet. Das Ergebnis der Überprüfung könnte beispielsweise dem Sachbearbeiter angezeigt werden. Der Aufbau des Speicherabbilds ist in nebenstehender Abbildung schematisch für ein Objekt der Klasse PKW dargestellt. Die aus den verschiedenen Klassen geerbten Attribute liegen dabei typischerweise direkt hintereinander. Weiterhin enthält das Speicherabbild eines Objekts einen Zeiger auf die sogenannte Tabelle virtueller Methoden, die der Ermittlung des Einsprungpunkts der konkreten Implementierung bei einem Methodenaufruf dient.Bjarne Stroustrup: Design und Entwicklung von C++. Addison-Wesley, Bonn 1994, ISBN 3-89319-755-9, S. 90–98.In der Programmiersprache C++ könnte die Implementierung der Klassen Fahrzeug, Kraftfahrzeug, Fahrrad, Motorrad, PKW, LKW folgendermaßen aussehen: class Fahrzeug { int Fahrzeugnummer; double Leergewicht; double ZulässigesGesamtgewicht;
bool PrüfeVerfügbarkeit() {}
class Kraftfahrzeug : Fahrzeug { double Höchstgeschwindigkeit; double Leistung;
bool PrüfeVerfügbarkeit() {}
class Fahrrad : Fahrzeug { double Rahmenhöhe;
class Motorrad : Kraftfahrzeug { bool PrüfeVerfügbarkeit() {}
class PKW : Kraftfahrzeug { int AnzahlSitzplätze;
bool PrüfeVerfügbarkeit() {}
class LKW : Kraftfahrzeug { double Nutzlast;
bool PrüfeVerfügbarkeit() {}
Anwendungen der Vererbung Die Vererbung ermöglicht bei der Softwareentwicklung eine Modellierung, die der menschlichen Vorstellung der realen Welt sehr nahe kommt. Es gibt sehr unterschiedliche Anwendungen des Vererbungsmechanismus. Nach wie vor ist umstritten, ob die Vererbung nur für sehr eng begrenzte Anwendungsbereiche verwendet werden sollte und ob ein Einsatz mit der hauptsächlichen Intention des Wiederverwendens von Code der Softwarequalität eher abträglich ist.Peter H. Fröhlich: Inheritance Decomposed. Inheritance Workshop, European Conference on Object-Oriented Programming (ECOOP), Málaga, 11. Juni 2002.Bertrand Meyer: The many faces of inheritance: A taxonomy of taxonomy. In: IEEE Computer. Vol. 29, 1996, S. 105–108.
Folgende Anwendungskontexte werden empfohlen oder tauchen in der Praxis auf:Donald Firesmith: Inheritance Guidelines. In: Journal of Object-Oriented Programming. 8(2), 1995, S. 67–72.
Subtyp-Vererbung: Bei dieser Art der Vererbung ist die erbende Klasse ein Subtyp der Basisklasse im Sinne eines abstrakten Datentyps. Dies bedeutet, dass ein Objekt des Subtyps an jeder Stelle eingesetzt werden kann, an der ein Objekt des Basistyps erwartet wird. Die Menge der möglichen Ausprägungen des Subtyps stellt eine Teilmenge derer des Basistyps dar. Vererbung zur Erweiterung: In der abgeleiteten Klasse wird neue Funktionalität gegenüber der Basisklasse ergänzt. Diese Variante der Vererbung stellt einen scheinbaren Widerspruch zur einschränkenden Subtyp-Vererbung dar. Die Erweiterung bezieht sich dabei aber auf zusätzliche Attribute.Die Menge der möglichen Ausprägungen des Subtyps bildet weiterhin eine Teilmenge des Basistyps, wenn lediglich die Attribute des Basistyps betrachtet werden. Diese Variante beinhaltet auch Anpassungen durch Überschreiben von Methoden, um beispielsweise Funktionalität zu ergänzen, die in der Basisklasse nicht relevant ist. Auch schließt diese Variante den Fall ein, dass nur ein Teil der Funktionalität einer abstrakten Klasse in der abgeleiteten – in diesem Fall ebenfalls abstrakten – Klasse implementiert wird, und zusätzlich erforderliche Implementierungen weiteren Spezialisierungen vorbehalten bleiben (Reification). Vererbung zur Unterstützung allgemeiner Fähigkeiten: Bei dieser Variante geht es darum, die Unterstützung von Basisfunktionalität einer Anwendungsarchitektur oder Klassenbibliothek zu etablieren. Eine Basisfunktionalität wie Serialisierbarkeit oder Vergleichbarkeit wird dabei durch eine abstrakte Klasse (Schnittstelle) deklariert – typische Bezeichner sind Serializablesiehe beispielsweise: MSDN, .NET Framework-Klassenbibliothek: ISerializable-Schnittstelle und Comparable.siehe beispielsweise: Java 2 Platform, Standard Edition, v 1.4.2, API Specification: Die Implementierung aller Anforderungen der Schnittstelle muss in der abgeleiteten Klasse erfolgen. Formal entspricht diese Art der Vererbung der Subtyp-Vererbung. Vererbung von Standardimplementierungen: Allgemeine für mehrere Typen verwendbare Funktionalität wird dabei in zentralen Klassen implementiert. Diese Variante dient der zweckdienlichen Wiederverwendung allgemeiner Programmteile (Mixin-Klasse).
Es gibt auch Verwendungen der Vererbung, die als nicht sinnvoll angesehen werden. Insbesondere bei den ersten Gehversuchen in objektorientierter Programmierung ergibt sich häufig eine aus der Begeisterung resultierende übertriebene Abstufung der Vererbungshierarchie, oft für eine simple zusätzliche Eigenschaft. Beispielsweise dürften für eine Klasse Person die Spezialisierungen WeiblichePerson und MännlichePerson in den wenigsten Fällen zweckmäßig sein und bei der Modellierung der eigentlich relevanten Aspekte eher behindern. Eine weitere fragwürdige Verwendung ist, wenn die erbende Klasse nicht in einer „ist-ein“-, sondern in einer „hat“-Beziehung zur Basisklasse steht, und eine Aggregation angebracht wäre. Häufig tritt dieser Fall in Verbindung mit Mehrfachvererbung auf. Apfelkuchen als Erbe von Kuchen und Apfel stellt ein bildhaftes Beispiel dieses Modellierungsfehlers dar, da Apfel keine sinnvolle Basisklasse ist.