Home » Object Pascal » Interfaces

Interfaces

Ein Interface wird von der Syntax her ähnlich deklariert wie eine Klasse. Es besitzt allerdings nur öffentliche (public) Methoden, die nicht implementiert werden. Klassen können von einem oder mehreren Interfaces ableiten und müssen dann die im Interface deklarierten Methoden auch implementieren. Dass eine Klasse ein bestimmtes Interface verwendet, bedeutet also, dass eine bestimmte Menge von Methoden zur Verfügung gestellt wird. Dies ist insbesondere bei verteilten Objektmodellen von Bedeutung (z.B. SOAP und CORBA).

Die Namen von Interfaces beginnen per Konvention mit einem großen I. Grundlegende Basisklasse aller Interfaces ist IInterface. Ähnlich wie Klassen von TObject erben alle Interfaces von IInterface. Da Interfaces aber keine Methodenimplementierung enthalten, wird nur die Verpflichtung geerbt, bestimmte Methoden anzubieten.

Beispiel für die Deklaration eines Interfaces:

type
 IMath = interface(IInterface)
   function Add(sum1, sum2: Integer): Integer;
   function Sub(sub1, sub2: Integer): Integer;
 end;

Das hier verwendete Schlüsselwort interface hat in diesem Fall nichts mit dem gleichnamigen Schlüsselwort beim Erstellen von Units zu tun.

Interfaces können einen GUID (Global Unique Identifier) verwenden, um eindeutig identifizierbar zu sein. In Delphi kann eine solche ID über die Tastenkombination Strg+Shift+G erzeugt werden:

type
 IMath = interface(IInterface)
 ['{A1229A9D-E207-4CBD-9B7E-FEFD9D3C1684}']
   function Add(sum1, sum2: Integer): Integer;
   function Sub(sub1, sub2: Integer): Integer;
 end;

Soll eine Klasse dieses Interface verwenden, wird wie folgt vorgegangen: Hinter dem Schlüsselwort class wird in Klammern die Basisklasse angegeben. Getrennt durch Kommata können hier Interfaces folgen.

Beispiel:

type
 TMyClass = class(TObject, IMath)

Nun ist die Klasse gezwungen, die Methoden, die zu dem Interface und dessen Vorfahren gehören, zu implementieren.

In unserem Fall sind das Add und Sub aus IMath und _AddRef, _Release und QueryInterface aus IInterface (unter Win32). Damit man die letzten drei Methoden (diejenigen aus IInterface) nicht selbst implementieren muss, sollte man eine Klasse, die Interfaces verwendet, nicht von TObject, sondern von TInterfacedObject ableiten. In dieser Klasse sind die IInterface-Methoden bereits implementiert, so dass diese einfach geerbt werden können:

type
 TMyClass = class(TInterfacedObject, IMath)
 public
   function Add(sum1, sum2: Integer): Integer;
   function Sub(sub1, sub2: Integer): Integer;
 end;

Werden mehrere Interfaces mit gleichen Methoden implementiert, müssen die Namenskonflikte aufgelöst werden. Dies geschieht dadurch, dass einer Methode einer anderen zugeordnet wird:

type
 TMyClass = class(TInterfacedObject, IMath, IMySecondInterface)
 function IMath.Add = Addition;