Zum Inhalt springen

Programmierkurs: Delphi: Pascal: Vererbung

Aus Wikibooks

Vererbung

[Bearbeiten]

Einleitung

[Bearbeiten]

Das Vererben von sämtlichen Methoden, Feldern, etc. von einer alten Klasse ist eine ganz wichtige Eigenschaft von Klassen.
So ist es z.B. möglich, von einer Klasse TWirbeltier die Klasse TMensch abzuleiten. So kann man eine bestehende Klasse spezialisieren, oder auch verändern.
Jede Klasse ist ein Nachkomme von TObject.

Deklaration

[Bearbeiten]

Es wird einfach hinter das Schlüsselwort class die Vorfahrklasse in Klammern gesetzt, und schon kann man die Nachkommenklasse benutzen.

TObject
[Bearbeiten]

Da jede Klasse ein Nachkomme von TObject ist, ist es bei Delphi nicht nötig, TObject extra hinzuschreiben. Deswegen sind die beiden Deklarationen absolut gleichwertig und gleichbedeutend:

type
  TMeineKlasse = class (TObject)   
  end;

oder

type
  TMeineKlasse = class
  end;
Beispiel
[Bearbeiten]
type
  TWirbeltier = class
  private
    AnzKnochen: Integer;
  public
    Lebt: Boolean;

    procedure Iss(Menge: Integer);
    function Gesundheit: Integer;
  end;
  

  TMensch = class (TWirbeltier)
  end;

TMensch besitzt alle Methoden und Felder von TWirbeltier. Folgender Aufruf ist also völlig legitim (abgesehen davon, dass Mensch.Gesundheit nicht gesetzt wurde):

var Mensch: TMensch;
begin
  Mensch := TMensch.Create;
  Mensch.Iss(10);
  Writeln(Mensch.Gesundheit);
  Mensch.Free;
end;

Ersetzen von Methoden und Feldern

[Bearbeiten]

Wenn man eine Methode/Feld in der Nachkommenklasse deklariert, die den selben Namen hat wie in der Vorfahrklasse, dann wird die Vorfahr-Methode/Feld durch die neu deklarierte ersetzt.

type
  TWirbeltier = class
  private
    AnzKnochen: Integer;
  public
    Lebt: Boolean;

    procedure Iss(Menge: Integer);
    function Gesundheit: Integer;
  end;
  

  TMensch = class (TWirbeltier)
    procedure Iss(Menge: Integer);
  end;

procedure TWirbeltier.Iss(Menge: Integer);
begin
  Writeln(Menge);
end;

procedure TMensch.Iss(Menge: Integer);
begin
  Writeln(Menge*2);
end;

var Mensch: TMensch;

begin
  Mensch := TMensch.Create;
  Mensch.Iss(10);
  Mensch.Free;
end.

Die procedure Iss von TMensch ersetzt Iss von der Vorfahrklasse. Und damit wird 20 ausgegeben werden.

Überschreiben von Methoden und Feldern

[Bearbeiten]

Wenn man eine Methode/Feld ersetzen will, aber trotzdem noch unter Umständen auf die Vorfahr-Methode/Feld zugreifen will, dann überschreibt man sie mit dem Schlüsselwort override und muss in der Vorfahrklasse diese Methode/Feld mit dem Schlüsselwort virtual kennzeichnen.
Die Vorfahr-Methode/Feld ist dann sozusagen virtuell im Hintergrund schlummernd.
Dann ist die virtuelle Vorfahr-Methode/Feld über das Schlüsselwort inherited zu erreichen.

type
  TWirbeltier = class
  private
    AnzKnochen: Integer; 
  public
    Lebt: Boolean;

    procedure Iss(Menge: Integer); virtual;
    function Gesundheit: Integer;
  end;
  

  TMensch = class (TWirbeltier)
    procedure Iss(Menge: Integer); override;
  end;

procedure TWirbeltier.Iss(Menge: Integer);
begin
  Writeln(Menge);
end;

procedure TMensch.Iss(Menge: Integer);
begin
  Writeln(Menge); 
  inherited Iss(Menge*2);  // hier wird die Vorfahr-Methode aufgerufen
end;

var Mensch: TMensch;

begin
  Mensch := TMensch.Create;
  Mensch.Iss(10);
  Mensch.Free;
end.

Hier wird erst 10 ausgegeben werden, dann 20.
Dies ist ein sehr großer Vorteil bei dem Überschreiben, dass man eine Methode sehr gut erweitern kann, ohne den Code nochmal abschreiben zu müssen.
Also in dem Beispiel: Wieso nochmal Writeln aufrufen? Wir benutzen einfach die virtuelle Methode.


dynamic
[Bearbeiten]

Anstatt des Schlüsselwortes virtual kann man auch dynamic benutzen. Jedoch arbeitet es nicht so schnell wie virtual. Die Benutzung ist aber genau dieselbe.


Pascal: Eigenschaften Inhaltsverzeichnis Pascal: Zugriff auf Klassen