Beiträge durchsuchen

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 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.