Zur Themenübersicht        

Billard: Vererbung

Erinnern wir uns einmal an die verschiedenen Stufen unseres Billardprojektes:

Stufe 1: Einfache Kugel: Eine Kugel bewegt sich auf dem Bildschirm

Stufe 2: Spielfeldkugel: Die Kugel bewegt sich in einem Spielfeld und wird von den Rändern des Spielfeldes reflektiert

Stufe 3: Fangkugel: Die Kugel kennt ferner eine Fangbox und bleibt stehen, wenn sie in der Fangbox ist. 
oder :    Reflexionskugel: Die Kugel kennt eine Reflexionsbox und wird auch von den Rändern der Reflexionsbox reflektiert.

In jeder Stufe hat die Kugel ein 'besseres' Gedächtnis. Außerdem hat sie mehr und bessere Fähigkeiten. 
Sie behält aber die Attribute und nicht geänderten Fähigkeiten (Dienste) der Stufe vorher.
  Attribute Dienste (Fhigkeiten)
Stufe 1 (TKugel) meinStift
XPos
YPos
aktuelleXGeschwindigkeit
aktuelleYGeschwindigkeit
+ init
+ setzePosition
+ setzeGeschwindigkeit
+ bewege
+ gibFrei
Sufe 2 (TSpielfeldkugel) Zusätzlich:
  kenntSpielfeld
Zusätzlich:
  + lerneSpielfeldKennen

Geändert:
  + bewege
Stufe 3 (TReflexionskugel) Zusätzlich:
  kenntReflexionsbox
Zusätzlich:
  + lerneReflexionsboxKennen

Geändet:
  + bewege

Wenn eine Klasse über sämtliche Attribute und Methoden einer anderen Klasse verfügt, aber Attribute hinzugekommen sind, oder Dienste (Fähigkeiten, manchmal spricht man auch von Methoden) hinzugekommen oder verändert worden sind, dann spricht man von einer Vererbungsbeziehung, oder einer Spezialisierung oder einer IST-Beziehung

Bezeichnungen am Beispiel:

IST Beziehung: Jede Spielfeldkugel IST natürlich auch eine Kugel, jede Reflexionskugel IST auch eine Spielfeldkugel und auch eine (einfache) Kugel
                       Jeder Pudel IST ein Hund. Jeder Hund IST ein Säugetier. Jeder Pudel IST natürlich auch ein Säugetier.

Klassen: Wir nennen die Klasse  TSpielfeldkugel eine Nachfolgerklasse oder Unterklasse oder Kind-Klasse der Klasse TKugel.
              Wir nennen die Klasse TKugel eine Vorgängerklasse oder Oberklasse oder Elternklasse der Klasse TSpielfeldkugel

Vererbung: Jedes Objekt einer Unterklasse  verfügt über alle Attribute und Methoden, welche die Objekte der Oberklasse besitzen. 
                   Es kann aber zusätzliche Attribute und Methoden besitzen. 
                   Ferner können Methoden der Oberklasse geändert - wir sagen auch überschrieben - werden.  

Anwendung auf unser Billardspiel:

Bisher haben wir die Veränderung der Fähigkeiten der Kugelklasse noch nicht unter diesem Aspekt betrachte. Wir werden die drei oben angegebenen Stufen nun im Folgenden unter dem Aspekt der Vererbung noch einmal durchdenken:

Beziehungsdiagramm ( so zu erstellen mit UMLed) :

 

Die Vererbungs- oder Spezialisierungs- oder einfach IST-Beziehung wird durch einen Pfeil von der Unterklasse zur Oberklasse dargestellt.

Eine Spielfeldkugel hat alle Attribute, die eine 'einfache' Kugel auch besitzt. Zusätzlich hat sie noch das Attribut 'kenntSpielfeld'. Sie besitzt ferner die zusätzliche Methode 'lerneSpielfeldKennen'. Die Methode 'bewege' muss geändert (überschrieben) werden, da eine Spielfeldkugel ja zusätzlich auf die Ränder des Spielfeldes reagieren soll. Entsprechendes gilt für die Reflexionskugel.

Alle Attribute der Oberklasse haben ein Doppelkreuz (#) statt des bisherigen Minuszeichens (-). Dieses Zugriffsrecht nennen wir protected (geschützt).  Alle Attribute einer Oberklasse müssen das Zugriffsrecht protected besitzen, wen sie von den Unterklassen benutzt werden sollen. Es bedeutet, dass die Units von Unterklassen auf dieses Attribute zugreifen können. Gegenüber anderen Klassen als Unterklassen sind die Attribute aber weiterhin geschützt. (Daher protected).

Hinweise zu UMLed:
UMLed bietet komfortable Möglichkeiten, in Unterklassen Methoden von Oberklassen zu überschreiben. 
Der Export nach Delphi arbeitet nur dann fehlerfrei, wenn die IST-Beziehung im Diagramm vorhanden ist. Ferner dürfen zu überschreibende Methoden in der Oberklasse natürlich nicht als 'nicht überschreibbar' gekennzeichnet werden. 

Codierung einer Nachfolgeklasse:

Wir schauen uns nun den Code der Klasse TSpielfeldkugel an, der bei richtigem Vorgehen übrigens weitgehend automatisch von UMLed erzeugt wird.

Beispiel Tabelle: Links Erklärung, rechts Code



In der Uses-Klausel muss die 
Unit der Oberklasse auftauchen.


So kennzeichnet man die Oberklasse

Wichtig: Auch hier Attribute als
  protected deklarieren.





override :alte Methode wird überschrieben.
             neue Methode











inherited bedeuted: geerbt.
Hier wird einfach der Code der Vorgänger-
klasse ausgeführt.

Dann folgt zusätzlich die 
  Reaktion auf die Reflexionsbox.
UNIT mTSpielfeldKugel;

interface

//--------------------  ggf Uses-Liste anpassen !  --------------------
uses mTKugel, mTReflexionsbox, mTSpielfeld, mSuM;

type
  TSpielfeldKugel = class(TKugel)

  protected //Attribute
    kenntSpielfeld : TSpielfeld;

     //Objektbeziehungen:
        // kenntTSpielfeld : TSpielfeld;

  public //Methoden
    procedure bewege; override;
    procedure lerneSpielfeldkennen (pKenntSpielfeld: TSpielfeld); virtual;

   end;

implementation

//+---------------------------------------------------------------------
//|         TSpielfeldKugel: Methodendefinition 
//+---------------------------------------------------------------------

//-------- bewege (public) ---------------------------------------------
procedure TSpielfeldKugel.bewege;
begin
  inherited bewege;

  //Reflexion an den Spielfeldrändern
  if self.xPos - 11 <= kenntSpielfeld.GibXPos
     then self.SetzexGeschwindigkeit(self.zxGeschwindigkeit*(-1));
  if self.xPos + 11 >= kenntSpielfeld.GibXPos + kenntSpielfeld.GibBreite
     then self.SetzexGeschwindigkeit(self.zxGeschwindigkeit*(-1));
  if self.yPos - 11 <= kenntSpielfeld.Gibypos
     then self.SetzeyGeschwindigkeit(self.zyGeschwindigkeit*(-1));
  if self.yPos + 11 >= kenntSpielfeld.Gibypos + kenntSpielfeld.gibHoehe
     then self.SetzeyGeschwindigkeit(self.zyGeschwindigkeit*(-1));

end;

//-------- lerneSpielfeldkennen (public) -------------------------------
procedure TSpielfeldKugel.lerneSpielfeldkennen (pKenntSpielfeld: TSpielfeld);
begin
  kenntSpielfeld := pKenntSpielfeld;
end;

end.

Download der entsprechenden Datei: Billard mit Vererbungsstrukturen

Zugehöriges UML-Diagramm: