Einzelnen Beitrag anzeigen

Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.396 Beiträge
 
Delphi 11 Alexandria
 
#4

AW: Tutorial Interfaces

  Alt 12. Apr 2017, 10:58
Man muss sich einfach darüber klar sein, dass ein Interface ganz bewusst nichts Konkretes ist, sondern lediglich eine Zusicherung. Das bedeutet, der Benutzer (im Sinne einer Klasse) des Interfaces muss die konkrete Implementation überhaupt nicht kennen, kann sich aber trotzdem sicher sein, dass alle im Interface deklarierten Properties und Methoden vorhanden sind. Dadurch wird eine einfache Erweiterbarkeit erreicht. Ein kleines Beispiel: nehmen wir an, wir haben die Klassen TDings und TConsumer. Letztere ruft eine Methode Blubb der Ersteren auf.
Delphi-Quellcode:
type
  TDings = class
  public
    procedure Blubb;
  end;

  TConsumer = class
  public
    procedure Wuppdi(const Dings: TDings);
  end;

...

procedure TConsumer.Wuppdi(const Dings: TDings);
begin
  Dings.Blubb;
end;
Alles cool, alles easy. Nun wollen wir das Programm erweitern und schreiben eine Klasse TBums, die ebenfalls eine Methode Blubb enthält. Die Consumer-Klasse soll sowohl mit TDings als auch mit TBums umgehen können. Was können wir tun? Mir fallen da ein paar Möglichkeiten ein:
- Überladen der Wuppdi-Methode
- Ableiten der TDings- und TBums-Klasse von einer gemeinsamen Elternklasse, die Blubb als (ggf. virtuelle oder dynamische) Methode einführt. Das macht dann eine Änderung des Parametertyps in den Typ der Elternklasse notwendig.
- Ändern des Parametertyps in TObject und Abfrage in der Methode, ob es sich um TDings oder TBums handelt, dann Typecast und Aufruf.

Das ist alles nicht so wirklich elegant und macht Änderungen an verschiedenen Stellen nötig. Hier kommen jetzt die Interfaces ins Spiel: man ändert einmalig den Parametertyp in einen Interfacetyp, in dem die Blubb-Methode vereinbart wird. TDings und TBums implementieren jetzt dieses Interface, TConsumer greift dann darüber auf die Methode zu. Soll später eine weitere Klasse TSchiessMichTot dazukommen, lässt man sie ebenfalls das Interface implementieren, schon kann TConsumer ohne jede Codeänderung auch damit umgehen.

Delphi-Quellcode:
type
  ISuperIntf = interface
    ['{01107754-046D-4A32-AC6F-D96BC2AECCE0}']
    procedure Blubb;
  end;

  TDings = class(TInterfacedObject, ISuperIntf)
  public
    procedure Blubb;
  end;

  TBums = class(TInterfacedObject, ISuperIntf)
  public
    procedure Blubb;
  end;

...

procedure TConsumer.Wuppdi(const SuperIntf: ISuperIntf);
begin
  SuperIntf.Blubb;
end;
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  Mit Zitat antworten Zitat