Step 01 - OOP und was nun noch gesagt werden muss (Teil 1/3)

 

1. Eckstein, Echstein, alles muss versteckt sein ;)

...oder: Das Geheimnisprinzip

Im Kurs Anfängerwissen haben wir angeschnitten, wo man Variablen deklarieren kann. Was wir hier nicht so genau dabei betrachtet haben ist, was die Gründe dafür sind. Wieso soll man es so machen und nicht anders? Zum Beispiel kann man ja ein Array einfach global deklarieren. Also direkt in var im Interface-Abschnitt, direkt unter der Zeile, in der Form1 deklariert ist. Aber was bringt es uns, wenn wir in einer anderen Unit auch ein Array mit dem gleichen Namen, aber für einen anderen Zweck nutzen wollen?
Und hier kommt die wichtigste Regel ins Spiel, wenn es um die Deklaration von Variablen/Feldern/Zugriffsgedöns geht:
Deklariere so global wie nötig, so lokal wie möglich!
Beachte zudem:
  • alle Variablen sollten möglichst aussagekräftig bezeichnet werden. (Lesbarkeit)
  • hat man nur globale Variablen, schafft dies Unübersichtlichkeit - wo wird was wann benutzt? (Wartbarkeit)
  • globale Variablen oder Objekte können von überall benutzt werden. In der OOP benutzt man hierfür jedoch s.g. "Properties" in den Objekten. Damit kann eine Eigenschafft eines Objekts als "Globale Variable" benutzt werden, wenn auf das Objekt zugegriffen wird. Näheres folgt noch.
  • globale Variablen verbrauchen immer den Speicher, den sie verbrauchen; lokale werden nur dann, wenn sie benutzt werden. (Speichereffizienz, sollte auch heutzutage bedacht werden!)
 
Beispiel für Deklaration und Verwendung von Properties:
type
  TAuto = class(TForm)
  private
    fColor     : TColor;
    fHeight    : Integer;
    fWidth     : Integer;
    fMaxWeight : Integer;
  public
    property Color             : TColor  read fColor     write fColor;
    property Height            : Integer read fHeight    write fHeight;
    property Width             : Integer read fWidth     write fWidth;
    property WeightLoadMaximum : Integer read fMaxWeight;

    constructor Create( AColor:TColor; AHeight, AWidth, AMaxWeight: Integer);
  end;
 
Das Schlüsselwort "write"/"read" sorgt dafür, dass wir auf die Eigenschafft schreibend/lesend zugreifen können.
 
Ist MyCar eine erstellte Instanz unseres Objektes...
  // so wäre das möglich:
  MyCar.Color  := clBlue;
  MyCar.Height := 1.3;
  MyCar.Width  := 1.6;
  MyCar.Length := 2.4;
  
  // das jedoch nicht:
  MyCar.WeightMaximum := 10000;
Grund hierfür ist einfach, dass wir keine Schreibberechtigung für die Eigenschafft WeightMaximum erstellt haben.
 

2. Methoden mal anders

Wie wir es aus dem Anfängerbereich bereits kennengelernt haben, gibt es verschiedene Möglichkeiten beim deklarieren von Parametern. Zur kurzen Wiederholung und Vertiefung einmal folgende Methode als Beispiel:
procedure initGame( APlayerName: String; var ALevel: Integer;
    const AGameType: Integer; APlayerList: TStrings);
 
Beschreibung der Parameter:
Parameter Beschreibung
APlayerName: String; Dies ist eine ganz normale Definition eines Parameters; Hierbei werden die Werte der Variable übergeben. d.h. wenn in der Methode initGame die Variable APlayerName verändert wurde so ist die ursprüngliche Variable dennoch unverändert.
=> Call by Value
var ALevel: Integer Hierbei wird auf jeden Fall eine Variable verlangt, da hierbei nur der Zeiger auf die Adresse, in der sich der Wert befindet, übertragen wird.
=> Call by Reference
const AGameType: Integer; Hierbei kann alles mögliche übergeben werden. Der Clue bei der Geschichte ist, dass weder der Wert noch die Referenz verändert werden kann.
=> geschütztes Objekt
APlayerList: TStrings Parametern, welche nicht einfache Datentypen sind, sondern eigene Klassen sind, stets die Referenz, also "der Zeiger" übertragen wird.
 
Somit dürfte der OOP-Bereich zum Thema der Sichtbarkeit erstmals erledigt sein :)