Vererbung

Vererbung

Von bereits bestehenden Klassen kann man ableiten, das heißt, die bereits vorhandene Funktionalität einer Klasse in einer anderen Klasse erweitern. Die Klasse, die bereits besteht und von der abgeleitet wird, nennt man Basisklasse. So kann es sein, dass man eine Klasse Student und eine Klasse Professor hat. Diese beiden Klassen haben gemeinsame Grundeigenschaften, wie zum Beispiel Vorname, Nachname und Adresse. Gleichzeitig kann aber auch jede dieser Klassen Bestandteile haben, die die andere Klasse nicht benötigt. Ein Beispiel hierfür wäre die Sozialversicherungsnummer - während diese beim Professor benötigt wird, ist das beim Studenten nicht der Fall.

Wenn man dieses Beispiel näher betrachtet, kristallisiert sich heraus, dass eine gemeinsame Basisklasse "Person" sinnvoll wäre, die allgemeine Daten, wie eben den Namen, enthält. Diese Klasse soll dann beim Beispiel des Professors um die Sozialversicherungsnummer erweitert werden. Zuerst müssen wir also nun die Klasse "Person" implementieren, von der wir später ableiten wollen:

public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string Address { get; set; }
}

Wir haben nun eine einfache "Person" Klasse, in der drei Variablen definiert sind. Nun wollen wir von dieser Klasse unsere Professor Klasse ableiten. In C# wird zum Ableiten der : Operator verwendet. Das heißt, die Syntax, um Professor von Person abzuleiten, würde folgendermaßen aussehen:

public class Professor : Person
{
...
}

In der Klasse Professor sind durch die Ableitung automatisch bereits die drei Variablen, die in der Person Klasse definiert wurden vorhanden, das heißt, wir brauchen den Vornamen, den Nachnamen und die Adresse im Professor nicht mehr zu implementieren.

public class Professor : Person
{
public string Sin { get; set; }
}

Nun haben wir der Klasse Professor noch die SIN (= social insurance number) hinzugefügt. Die Klasse hat jetzt vier Variablen: Vorname, Nachname, Adresse und Sozialversicherungsnummer. Man kann in der Basisklasse nicht nur Variablen definieren, sondern auch Methoden, die ebenfalls in abgeleitete Klassen übernommen werden. Es kann allerdings vorkommen, dass man eine Methode, die von der Basisklasse übernommen wurde, in der abgeleiteten Klasse etwas anders implementieren möchte. Dazu ist es nötig, dass diese Methode in der Basisklasse mit dem Schlüsselwort "virtual" gekennzeichnet wird. In der abgeleiteten Klasse muss man die zu überschreibende Methode mit override kennzeichnen:

public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string Address { get; set; }

public virtual void Write ()
{
Console.WriteLine("First name: " + FirstName +
"\nLast name: " + LastName +
"\nAddress: " + Address);
}
}

public class Professor : Person
{
public string Sin { get; set; }

public override void Write ()
{
Console.WriteLine("First name: " + FirstName +
"\nLast name: " + LastName +
"\nAddress: " + Address +
"\nSocial insurance number: " + Sin);
}
}

Hier wurde die Write() Methode als Beispiel genommen. Beispielsweise könnte man sich in der Write Methode bei der Person Vorname, Nachname und Adresse ausgeben lassen. In der Write Methode des Professors ist es jedoch nötig, sich auch die Sozialversicherungsnummer ausgeben zu lassen. Das override macht es möglich, dass der Name und die Verwendung der Write Methode bei der Professor Klasse genau gleich bleiben, während sie jedoch komplet neu implementiert werden kann. Es werden allerdings nur Variablen und Methoden implizit von der Basisklasse übernommen, Konstruktoren nicht. Das heißt, wenn man nicht den Standardkonstruktor verwendet, muss man den Konstruktor in der abgeleiteten Klasse wieder implementieren. Man kann jedoch in der abgeleiteten Klasse den Konstruktor der Basisklasse aufrufen, also das Ganze an den Konstruktor der Basisklasse "weiterleiten". Das funktioniert mit dem Schlüsselwort "base". Folgendes Beispiel veranschaulicht dies:

public class Person
{
public Person (string firstName, string lastName)
{
this.FirstName = firstName;
this.LastName = LastName;
}
public string FirstName { get; set; }
public string LastName { get; set; }
public string Address { get; set; }
}

public class Professor : Person
{
Professor (string firstName, string lastName, string Sin) : base (firstName, lastName)
{
this.Sin = Sin;
}

public string Sin { get; set; }
}

Hier wird in der Klasse "Professor" der Konstruktor der Basisklasse aufgerufen und anschließend noch "Sin" initialisiert. C# unterstützt keine Mehrfachvererbung, das heißt, es ist immer nur möglich, von einer Klasse abzuleiten.


Vollständiger Programmcode mit Beispiel

public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string Address { get; set; }

public virtual void Write ()
{
Console.WriteLine("First name: " + FirstName +
"\nLast name: " + LastName +
"\nAddress: " + Address);
}
}

public class Professor : Person
{
public string Sin { get; set; }

public override void Write ()
{
Console.WriteLine("First name: " + FirstName +
"\nLast name: " + LastName +
"\nAddress: " + Address +
"\nSocial insurance number: " + Sin);
}
}

class Program
{
static void Main(string[] args)
{
Person p = new Person();
p.FirstName = "Daniel";
p.LastName = "Mayr";
p.Address = "Musterstraße 4, 4040 Linz";

p.Write();

Professor prof = new Professor();
prof.FirstName = "Hugo";
prof.LastName = "Berger";
prof.Address = "Musterstraße 5, 4040 Linz";
prof.Sin = "48340283490";

prof.Write();
}
}