Beiträge durchsuchen

Zugriff auf Objekte

Zugriff auf Objekte

Zur Erinnerung noch einmal unsere Auto-Klasse von vorhin:

type
 TAuto = class
 private
 FFarbe: string;
 FBaujahr: integer;
 procedure SetFarbe(Farbe: string);
 public
 property Farbe: string read FFarbe write SetFarbe;
 end;

Diese Klasse enthält folgende Klassenkomponenten:

Diese Komponenten sind im Bauplan (der Klasse) vorgegeben, können jedoch in allen Instanzen dieser Klasse unterschiedliche Werte haben. Ein Zugriff auf diese Komponenten ist deshalb nur über die Namen der Instanzen (Objektreferenzen) sinnvoll und möglich.
Wurde also über

var MeinAuto: TAuto;

eine Objektreferenz definiert und die Instanz mit create erzeugt, lassen sich die Komponenten folgendermaßen ansprechen:

var MeinAuto: TAuto;
begin
 MeinAuto := TAuto.Create;
 MeinAuto.SetFarbe('rot');
 MeinAuto.Farbe := 'rot';

Auf private-Felder (FFarbe und FBaujahr) sollte nur von Methoden der Klasse TAuto selbst aus zugegriffen werden. Beispiel:

 MeinAuto.FFarbe := 'rot';
 MeinAuto.FBaujahr := '1980';

Zugriffsrechte

Nun kommen wir zu den Zugriffsrechten, in unserem Fall private und public.
Private Komponenten dürfen nur innerhalb der Unit angesprochen werden, in dessen Interface-Teil die betreffende Klasse definiert wurde.
Öffentliche (public) Komponenten dürfen darüber hinaus auch überall dort angesprochen werden, wo die betreffende Unit (durch uses) zur Nutzung bereit gestellt wird.
Dies stellt auch den Grund der kompliziert erscheinenden Verwendung der property dar.
Soll ein Attribut (hier die Farbe) aus einer anderen Unit, die möglicherweise ein anderer Programmierer geschrieben hat, heraus verändert werden, kann dies zu Problemen führen. Die Zeile

property Farbe: string read FFarbe write SetFarbe;

bedeutet, dass „Farbe“ wie ein normales Attribut verwendet werden kann. Da es im public-Abschnitt steht, ist auch ein Zugriff aus anderen Units möglich. Wird der Wert von Farbe ausgelesen (read) gibt die Instanz automatisch den Wert von FFarbe zurück. Soll dagegen die Eigenschaft „Farbe“ neu gesetzt werden (write), wird SetFarbe, die Prozedur im private-Teil, aufgerufen. In ihr könnte nun geprüft werden, ob der übergebene Wert beispielsweise eine gültige Farbe für dieses Auto darstellt. Wenn ja, kann die Prozedur das Datenfeld FFarbe setzen:

procedure TAuto.SetFarbe(Farbe: string);
begin
 if (farbe = 'rot') or (farbe = 'blau') or (farbe = 'gruen') then
 FFarbe := Farbe;
end;

Darüber hinaus gibt es weitere Sichtbarkeitsattribute:

private Ein private-Element kann nur innerhalb der gleichen Unit verwendet werden. Aus anderen Units ist ein Zugriff nicht möglich.
protected Ein protected-Element ist wie ein private-Element innerhalb der gleichen Unit verwendbar. Darüberhinaus haben alle abgeleiteten Klassen darauf Zugriff, unabhängig davon, in welcher Unit sie sich befinden.
public public-Elemente unterliegen keinen Zugriffsbeschränkungen.
published published-Elemente haben dieselbe Sichtbarkeit wie public-Elemente. Zusätzlich werden diese Element im Objektinspektor angezeigt, weshalb nicht alle Typen als published-Element eingesetzt werden können.
automated automated ist nur noch aus Gründen der Abwärtskompatibilität vorhanden. Der Einsatz erfolgte in Zusammenhang mit OLE-Automatisierungsobjekten und nur in Klassen, die von TAutoObject (Unit OleAuto) abgeleitet waren. Für TAutoObject aus der Unit ComObj wird automated nicht mehr verwendet.
strict private strict private-Elemente sind nur innerhalb der Klasse sichtbar. Andere Klassen können nicht darauf zugreifen, auch wenn sie sich in derselben Unit befinden. (seit Delphi 8)
strict protected strict protected-Elemente sind innerhalb der Klasse und in allen davon abgeleiteten Klassen sichtbar, jedoch nicht in anderen (nicht verwandten) Klassen derselben Unit. (seit Delphi 8)

Zuweisungen für Objektreferenzen

Angenommen wir haben zwei unterschiedliche Auto-Instanzen in unserem Arbeitsspeicher:

var auto1, auto2: TAuto;
...
...
auto1 := TAuto.Create;
auto2 := TAuto.Create;

Beide sollen verschiedene Werte enthalten. Wir haben also folgende Situation:

Objektreferenzen

Was passiert nun, wenn wir die Zuweisung

auto2 := auto1;

vornehmen? Möglich ist das auf jeden Fall, da beide den gleichen Aufbau (nach dem Bauplan der Klasse TAuto) haben.
Im Arbeitsspeicher sieht es aber so aus:

Speicherloch

D. h. im Hauptspeicher ändert sich gar nichts. Allerdings zeigen jetzt beide Referenzen auf das zuerst angesiedelte Objekt, das bisher nur unter dem Namen auto1 bekannt war. Es wurde nur die Verweisadresse (wo sich die Instanz im Arbeitsspeicher befindet) von auto2 auf die von auto1 gesetzt.

Die zweite Instanz existiert immer noch, besitzt allerdings keine Referenz mehr, so dass ihr Platz im Arbeitsspeicher nicht mehr freigegeben werden kann (Speicherloch).