ist eine Säule des objektorientierten Programmierens OOP:


UML-Klassendiagramm: Vererbung


Eigenschaften und Methoden einer Oberklasse lassen sich durch Unterklassen "erben", d.h. einfach übernehmen bzw. wiederverwenden. Man spricht dabei von „Code-Wiederverwendung”.

Vererbung als dritter Beziehungstyp zwischen Objekten stellt eine "Ist"-Beziehung dar.
(Komposition und Aggregation sind dagegen "Hat"-Beziehungen.)


Im folgenden Beispiel ist ein Kunde eine Person.


UML-Klassendiagramm: Person - Kunde

UML-Klassendiagramm: Der Vererbungspfeil ist von der erbenden Unterklasse zur vererbenden Oberklasse gerichtet. Die Pfeilspitze ist geschlossen und nicht ausgefüllt.


  1. public class Person         // Definition der Oberklasse
  2. {
  3.     protected string name;  // Zugriffsmodifizierer protected -> Zugriff auf Member ist auch in
  4.                             // Unterklasse möglich
  5.     public Person()         // Standardkonstruktor muss vorhanden sein
  6.     {
  7.         Console.WriteLine("Standardkonstr. Oberklasse Person");
  8.     }
  9.     public Person(String name)  // "Allgemeiner" oder "Spezieller" Konstruktor
  10.     {
  11.         this.name = name;
  12.         Console.WriteLine("Spezieller Konstr. Oberklasse Person");
  13.     }
  14.     public string Name          // Property
  15.     {
  16.         get { return name; }
  17.         set { name = value; }
  18.     }
  19. }


Damit der Zugriff in der Unterklasse auf die von der Oberklasse geerbten Eigenschaften erfolgen kann, müssen die Eigenschaften in der Oberklasse als protected deklariert werden.


  1. public class Kunde : Person  // Unterklasse erbt von der Oberklasse Person
  2. {
  3.     public Kunde(string name) {
  4.         this.name = name;
  5.         Console.WriteLine("Spezieller Konstr. Unterklasse Kunde");
  6.     }
  7.     public string KundenNr { get; set; }
  8. }


Die Unterklasse Kunde übernimmt alle Eigenschaften und Methoden der Oberklasse Person. Sie brauchen deshalb nicht neu definiert zu werden, d.h. der Code wird „wiederverwendet”.

In der Unterklasse müssen nur die Ergänzungen zur Oberklasse definiert zu werden.


Objekterzeugung und -zugriff erfolgt wie gewohnt:

  1. class Program
  2. {
  3.     static void Main(string[] args)
  4.     {
  5.         Person p = new Person("Person");  
  6.         Console.WriteLine(p.Name + "\n");
  7.  
  8.         Kunde k = new Kunde("Kunde");
  9.         k.KundenNr = "1";
  10.         Console.WriteLine(k.Name + "\t" + k.KundenNr);
  11.  
  12.         Console.ReadKey();
  13.     }
  14. }


Die Ausgabe des Programms ist:

Ausgabe des Programms

Man sieht, dass bei der Erzeugung des Objekts der Unterklasse zuerst der Konstruktor der Oberklasse und danach der Konstruktor der Unterklasse aufgerufen wird. Wie ist das zu erklären?


Verschachtelte Objekte

Das Unterklassenobjekt beinhaltet das Oberklassenobjekt. Das Oberklassenobjekt ist also ein Teil des Unterklassenobjekts:


Ein Objekt der Oberklasse ist ein Teil des Objekts der Unterklasse

Ein Objekt der Oberklasse ist ein Teil des Objekts der Unterklasse

Aus diesem Grund müssen der Reihe nach alle Konstruktoren von innen nach außen, d.h. beginnend mit der Oberklasse bis hin zur letzten Unterklasse aufgerufen werden.


Konsequenzen für Typkonvertierungen

Daher lassen sich Unterklassenobjekte auch in Oberklassenobjekte umwandeln.

  1.  Person p2 = k;  // implizite Typumwandlung ist möglich, weil alle Bereiche des Personenobjekts definiert werden können.
  2.  Console.WriteLine(p2.Name);
  3.  Console.WriteLine(p2.Name + "\t" + p2.KundenNr);  // nicht möglich, weil ein Objekt der Klasse Person keine KundennNr hat.


Ausgabe des Programms

Natürlich gehen bei der Typumwandlung alle zusätzlichen Eigenschaften und Methoden der Unterklasse verloren. Nur das innere Objekt bleibt erhalten.
Auch eine explizite Typumwandlung in diese Richtung ist möglich und bewirkt das gleiche:

  1.  Person p2 = (Person)k;  // auch die explizite Typumwandlung ist hier möglich


Ein Objekt der Oberklasse lässt sich dagegen nicht zu einem Objekt der Unterklasse umwandeln:

  1.  Kunde k2 = p; // umgekehrt nicht möglich

Die zusätzlichen Bereiche der Unterklasse wären dabei alle nicht definiert.


Auch der Versuch einer expliziten Umwandlung in diese Richtung schlägt fehl. Sie würde zur Laufzeit eine Exception auslösen:

  1.  Kunde k2 = (Kunde)p; //explizite Typumwandlung mit Typecast führt zur Laufzeit zu InvalidTypeCastException

Interessanterweise ist diese explizite Umwandlung möglich:

  1.  Kunde k2 = (Kunde)p2; //ist möglich, weil p2 in Wirklichkeit eine Referenz auf ein Objekt vom Typ Kunde enthält.

Durch die obige Typkonvertierung von Objekt k zu Objekt p2 wurde tatsächlich lediglich der Typ der Referenz konvertiert, nicht das Objekt selbst. Was eine Grundvoraussetzung für das Konzept der sogenannten Polymorphie ist.



Last modified: Thursday, 5 September 2019, 11:02 AM