HSG

Aktuelle Seite: HSG/Fächer/Informatik/Material

Polymorphie von Methoden

Erinnerung:

Angenommen, wir haben zwei Zeiger oA und oB auf Objekte vom Typ TA und TB. Beide haben die Methode "tuewas", die aber durchaus Verschiedenes tun können. Wie unterscheidet der Compiler zwischen den beiden gleichlautenden Methoden?
Klar, nach dem Typ! Die Bindung zwischen der Variablen oA und der Methode tuewas wird nach dem Typ von oA zur Compilierzeit bestimmt. Man redet von früher Bindung oder statischer Bindung.

Experimentiermodell

An dem UML-Klassendiagramm sieht man, dass die Methode wuerfele dreimal auftaucht.
In einem kleinen Programm (vererbung3.zip ) sollen nun die verschiedenen Fälle, zwischen den Methoden zu unterscheiden, untersucht werden.

Statische, frühe Bindung

.......
type
  TW = class(tObject)
  private
    FZahl : integer;
  public
    procedure SetZahl(a : integer);
    function GetZahl : integer;
    procedure wuerfele;
  end;

  TW4 = class(TW)
  public
    procedure wuerfele;
  end;

  TW6 = class(TW)
  public
    procedure wuerfele;
  end;
  .......
  implementation
  ........
  procedure TW.wuerfele;
  begin
    setZahl(0);
  end;

  procedure TW4.wuerfele;
  begin
    setZahl(Random(4)+1);
  end;

  procedure TW6.wuerfele;
  begin
    setZahl(Random(6)+1);
  end;


Man kann w mit w4, w6 oder wA belegen, immer wird mit w.wuerfele nur die Methode wuerfele1 aufgerufen (als Augenzahl wird 0 ausgegeben).

Dynamische, späte Bindung

.......
type
  TW = class(tObject)
  private
    FZahl : integer;
  public
    procedure SetZahl(a : integer);
    function GetZahl : integer;
    procedure wuerfele; virtual; // legt VMT an
  end;

  TW4 = class(TW)
  public
    procedure wuerfele; override; // bewirkt Eintrag in VMT
  end;

  TW6 = class(TW)
  public
    procedure wuerfele; override; // bewirkt Eintrag in VMT
  end;


Das Schlüsselwort virtual bewirkt das Anlegen einer sogenannten virtuellen Methoden-Tabelle VMT

TypAdresse der wuerfele-Methode
TWwuerfele1

Mit dem Schlüsselwort override wird jeweils ein Eintrag in die VMT hinzugefügt.

TypAdresse der wuerfele-Methode
TWwuerfele1
TW4wuerfele2
TW6wuerfele3


Jetzt wird bei jedem Aufruf zuerst der Typ der Belegung der polymorphen Variablen w bestimmt und aus der VMT die "richtige" wuerfele-Methode herausgesucht. Dh. die Bindung zwischen Variable und Methode wird erst während der Laufzeit ermittelt und kann sich natürlich auch während der Laufzeit änderen. Man spricht von später Bindung bzw. von polymorphen Methoden.
Ein Test zeigt die Richtigkeit der Überlegungen. Es ist außerdem instruktiv, die Schlüsselwörter virtual bzw. override vorübergehend wegzulassen und die Auswirkungen zu studieren.

Abstrakte Methoden

Im Beispiel erzeugte die Methode wuerfele in TW eine Augenzahl 0. Das war für obige Experimente ganz nützlich, ist aber im Allgemeinen sinnlos. Eigentlich sollte wuerfele in TW gar nichts tun. Gut, das läßt sich mit einem leeren Prozedurrumpf erreichen. Besser ist es, in diesem Fall durch das Schlüsselwort abstract anzuzeigen, dass eigentlich nur eine VMT angelegt werden soll, aber kein Aufruf der "allgemeinen" wuerfele-Methode vorgesehen ist. In diesem Fall entfällt natürlich auch die unnötig gewordene Implementierung.

type
  TW = class(tObject)
  private
    FZahl : integer;
  public
    procedure SetZahl(a : integer);
    function GetZahl : integer;
    procedure wuerfele; virtual; abstract; // legt nur VMT an
  end;