Verbergen, überschreiben, überladen
Das Hinzufügen neuer Attribute, Eigenschaften oder Methoden in Unterklassen ist eine praktische Sache. Was passiert aber, wenn ein vermeintlich neues Element den gleichen Namen verwendet wie ein Element der Vorfahrenklasse?
Elemente gleichen Namens können einander innerhalb verwandter Klassen
- verbergen
- überschreiben
- überladen
Verbergen geerbter Elemente
Das Prinzip „Verbergen“ besteht darin, in einer Nachkommenklasse den Namen eines geerbten Elements neu zu vergeben. Dies kann jede Art von Klassen-Elementen betreffen.
type TBerufstaetig = class(TMensch) private FKontoNr: integer; FBankleitzahl: integer; public procedure GehaltZahlen; end; TManager = class(TBerufstaetig) private FGehalt: real; FZulagen: real; FAnzahlMitarbeiter: integer; public procedure GehaltZahlen; end;
Durch die Deklaration von GehaltZahlen in der Klasse TManager wird die gleichnamige Methode von TBerufstaetig verborgen. Wird jetzt an einer Instanz von TManager diese Methode aufgerufen, wird nicht – wie bisher – der Code von TBerufstaetig ausgeführt, sondern die neue Prozedur GehaltZahlen, die nur für TManager-Instanzen und deren Nachkommen gilt.
Die Methoden müssen dazu nur im Namen übereinstimmen, die Parameter dürfen sich unterscheiden.
Falls die von TBerufstaetig geerbte Methode dennoch benötigt wird, kann sie mit
inherited GehaltZahlen;
aufgerufen werden.
Normalerweise wird in der neuen Methode inherited dazu benutzt, um die „alte“ geerbte Methode aufzurufen.
Überschreiben
Das Überschreiben soll am Beispiel von Eigenschaften (s. Teil „Zugriff auf Objekte„) gezeigt werden. Dazu erweitern wird die oben verwendete Klasse TMensch um eine mögliche Eigenschaft:
type TMensch = class private FVorname: string; FNachname: string; FGeburtstag: TDate; FGeschlecht: string; procedure SetVorname(vorname: string); public property Vorname: string read FVorname write SetVorname; end;
Es besteht nun Lese- und Schreibzugriff auf die Eigenschaft Vorname. Wir verändern die Klasse etwas und bilden eine Klasse TMensch, die nur noch Lesezugriff hat. Von dieser Klasse soll die Klasse TPerson abgeleitet werden, die zusätzlich Schreibzugriff auf Vorname hat:
type TMensch = class private FVorname: string; FNachname: string; FGeburtstag: TDate; FGeschlecht: string; protected procedure SetVorname(vorname: string); property Vorname: string read FVorname; end; TPerson = class(TMensch) public property Vorname write SetVorname; end;
In TMensch ist die Eigenschaft Vorname nun nur noch private, d.h. Zugriffe aus anderen Units sind verboten; außerdem hat sie nur Leserechte. TPerson ist ein direkter Nachkomme von TMensch mit dem Unterschied, dass die Eigenschaft Vorname hier nun wieder öffentlich (public) ist und Lese- und Schreibzugriff darauf besteht. Die Eigenschaft Vorname von TMensch wird dadurch überschrieben. Erkennbar ist das daran, dass kein Typ angegeben ist. Würde ein Typ angegeben werden, würde die Eigenschaft nicht überschrieben, sondern verdeckt werden.
Beim Überschreiben von Eigenschaften in Unterklassen darf das Spektrum der Zugriffsrechte (read, write) nur erweitert, aber nicht eingeschränkt werden. Übernommene Zugriffsrechte dürfen verändert werden. Es dürfte also in einer Unterklasse von TPerson statt read FVorname eine Funktion zum Lesen verwendet werden, z.B. read GetVorname.
Wie das Überschreiben von Methoden funktioniert, ist im Kapitel über virtuelle und abstrakte Methoden beschrieben.
Überladen von Methoden
Auch in Prozeduren und Funktionen, die zu einer Klasse gehören, ist das Überladen möglich. Eine Beschreibung dazu ist im Abschnitt „Prozeduren und Funktionen“ zu finden.