HSG

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

Erzeugung und Vernichtung von Tochterobjekten bei der Aggregation

Es soll an einem kleinen Beispiel eine mögliche Realisierung einer "hat-Beziehung" aufgezeigt werden. Wie in folgendem Klassendiagramm gezeigt, soll ein Spiel-Objekt zwei Würfel-Objekte "haben".

Das Spiel-Objekt soll für Erzeugung und Vernichtung der beiden Würfel-Objekte verantwortlich gemacht werden. Bei Erzeugung des Spiel-Objekts sollen automatisch die Wuerfel-Objekte mit erzeugt werden. Das kann durch eine Erweiterung des TSpiel-Konstruktors geschehen. Ebenso soll der Destruktor die Freigabe des Speichers der Würfel-Objekte übernehmen. In einem ersten Schritt wird die Beziehung durch die beiden Referenzvariablen Wuerfel1 und Wuerfel2 in der Klassendefinition von TSpiel zum Ausdruck gebracht. Die zusätzliche Funktionalität des Konstruktors und des Destruktors macht eine Erweiterung der ererbten Methoden "Create" und "Destroy" erforderlich.

  TSpiel = class(TObject)
  private
    Wuerfel1, Wuerfel2 : TWuerfel;
  public
    constructor Create;
    destructor Destroy;
    procedure wuerfeln;
    function wurf1 : byte;
    function wurf2 : byte;
  end;
Es ist zu bedenken, dass eine "Neudefinition" des Konstruktors den alten nicht ersetzt, sondern nur "überdeckt". Dh. es gibt (mindestens) zwei Konstruktoren mit dem gleichen Namen. Der "alte" Konstruktor hat nun aber eine Funktionalität, die erhalten bleiben muss. Daher besteht die Möglichkeit, mit Hilfe eines vorangestellten "inherited" den alten Konstruktor aufzurufen, der dann z.B. nötige Speicherbelegungen durchführt. Anschließend können die eigenen Erweiterungen angefügt werden. Diese Reihenfolge muss eingehalten werden. So würde ein Zugriff auf ein Datenfeld "Wuerfel1" eines noch nicht existierenden Objekts natürlich zu einem Fehler führen.

  constructor TSpiel.Create;
  begin
    inherited Create; // inherited;  hat gleiche Wirkung
    Wuerfel1 := TWuerfel.Create;
    Wuerfel2 := TWuerfel.Create;
  end;
Bei der Freigabe des Speichers muss die umgekehrte Reihenfolge eingehalten werden. Zuerst wird der Speicher der Tochter-Objekte, dann der eigene Speicher freigegeben.

  destructor TSpiel.Destroy;
  begin
    Wuerfel1.Free;
    Wuerfel2.Free;
    inherited Destroy;
  end;
"Eine wesentlichr Eigenart für Aggregationen ist, dass das Ganze stellvertretend und übergreifend für seine Einzelteile handelt, d.h. Operationen übernimmt, die dann an die Einzelteile weitergeleitet (propagiert) werden." [Oesterreich, Objektorientierte Softwareentwicklung, S.57] Im Beispiel werden Anfragen nach den Wurfergebnissen vom Spiel-Objekt zu den Würfel-Objekten weitergeleitet. Für den Benutzer bleibt das transparent.

  function TSpiel.wurf1 : byte;
  begin
    Result := Wuerfel1.GetAugen;
  end;
Ein kleines Test-Projekt führt das Gesagte aus.

Download