Published property getter/setter dirüber implements property

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
Antworten
schlumie
Beiträge: 5
Registriert: Fr 11. Mär 2016, 12:26

Published property getter/setter dirüber implements property

Beitrag von schlumie »

Man kann ja Interfaces über eine Membervariable implementieren lassen was hervorragend funktioniert. Ich würde aber gerne ein property davon publishen und/oder ggf. die Getter/Setter Funktionen des implements Interface direkt dafür verwenden um mir Wraperfunktionen zu ersparen. Geht soetwas?

Code: Alles auswählen

 
type
ICommon = Interface(IInterface)
    ['{6b10544a-ddb0-43de-9612-348f547110da}']
    function GetTest() : Boolean;
    property Test : Boolean read GetTest;
end;
 
TTestLabel = class(ICommon)
 fCommon : ICommon;
 
 function GetTestWrap() : Boolean; //dont want to need this...
 property CommonInterface : ICommon read fCommon implements ICommon;
published
// property Test;  // not working...
// property Test : Boolean read GetTest write SetTest default False; // not working
// property Test : Boolean read fCommon.GetTest write fCommon.SetTest default False; // not working
// property Test : Boolean read ICommon.GetTest write ICommon.SetTest default False; // not working
  property Test : Boolean read GetTestWrap ; // working but more code..
end;
 
implementation
 
function TTestLabel.GetTestWrap() : Boolean; // dont want to write wrappers for each function...
begin
  Result:=fCommon.GetTest(); // just wrap interface function...
end;
 

Danke!

Warf
Beiträge: 1910
Registriert: Di 23. Sep 2014, 17:46
OS, Lazarus, FPC: Win10 | Linux
CPU-Target: x86_64

Re: Published property getter/setter dirüber implements prop

Beitrag von Warf »

Zum einen haben Properties (genauso wie Felder/variablen) in interfaces nichts verloren, da diese den Zustand des Objektes betreffen, und Interfaces nur Methoden nach außen definieren sollen (daher auch der Name Schnittstelle), da Schnittstellen immer möglichst klein gehalten werden sollen.

Wenn du es aber dennoch so machen möchtest, warum machst du es nicht einfach so?

Code: Alles auswählen

  ITestInterface = interface
    function GetTest: boolean;
    property Test: boolean read GetTest;
  end;
 
  TTestKlasse = class(ITestInterface)
  private
    function GetTest: boolean;
  end;
 
implementation
 
function TTestKlasse.GetTest: Boolean;
begin
  Result:=True;
end


Warum du noch einen Wrapper dazu verwendest verstehe ich nicht so ganz

schlumie
Beiträge: 5
Registriert: Fr 11. Mär 2016, 12:26

Re: Published property getter/setter dirüber implements prop

Beitrag von schlumie »

Wenn man interfaces über implements property komplett übernimmt/zuweist, dann finde ich, sind auch propertys sinnvoll und sind auch erlaubt und funktionieren auch. Wenn Interfacesfunktionen wie meist selbst implementiert werden dann hast du recht das properties vielleicht unpassender sind.
Wie gesagt bräuchte ich aber eine published property und da man die Sichtbarkeit natürlich über das interface nicht definieren kann würde ich gerne die property druchaus über die Klasse selbst (nochmal) defnieren/publishen, dazu wären die Funktionen des übernommen Interfaces hilfreich bzw. machen die genau das was ich brauche. Meine Frage war ob man die Funktionen des über implements übernommen/zugewiesenen Interface direkt in der property Anweisung der Klasse verwenden kann, oder wie im Beispiel nur mit einer Wrapperfunktion...

Marsmännchen
Beiträge: 294
Registriert: So 4. Mai 2014, 21:32
OS, Lazarus, FPC: Windows 10 64bit, Lazarus 2.0.10
CPU-Target: 64bit
Wohnort: Oranienburg

Re: Published property getter/setter dirüber implements prop

Beitrag von Marsmännchen »

In Interfaces stecke ich noch nicht allzu tief drin, aber ihre Systematik kenne ich von anderen Programmiersprachen (Java, C#, VB) her. Von der Logik her stellen sie einen Vertrag dar: Jeder, der ein Interface implementiert ist auch verpflichtet, alle seine Funktionen selbst(!) zu implementieren. Jeder, der eine Klasse über deren Interface benutzt kann daher sicher sein, dass diese Klasse die Funktionalität auch zur Verfügung stellt.
Das Interface selbst stellt - soweit ich es kenne - die Funktionalitäten selbst nicht zur Verfügung, sondern nur deren Methodenrümpfe. Daher kann über eine Property meines Erachtens auch nicht direkt auf die nicht vorhandenen Funktionalitäten des Interfaces zugegriffen werden, sondern nur über die konkrete Implementierung in der jeweiligen Klasse. Natürlich bleibt es einem unbenommen, in einer Klasse eine Membervariable vom Typ Interface anzulegen. Dann muss aber auch (im Konstruktor, spätestens vor Verwendung) diese Variable mit einem konkreten Objekt einer das Interface implementierenden Klasse referenziert werden. Dann kann ich auf diese konkrete Funktionalität zugreifen, auch in einer Property. Ich wüsste nicht, wie das mit den leeren Methodenrümpfen eines Interfaces gehen sollte. Oder ist das in Freepascal völlig anders???
Ich mag Pascal...

schlumie
Beiträge: 5
Registriert: Fr 11. Mär 2016, 12:26

Re: Published property getter/setter dirüber implements prop

Beitrag von schlumie »

Danke für die Antworten. Ich habe die Implementierungen/create/destory usw nicht ins Beispiel genommen damit es nicht zu lange/verwirrend wird und meine Farge ja eher auf die published property/interface abzielte. Die Sache man ein Interface über eine property in die eigene Interfacesliste der Klasse übernehmen kann ist eine Funktion von FPC. Ich will eine Funktionalität die mehrere Methoden und propertys umfasst und in X Klassen gebraucht wird nicht bei jeder der Klassen (in der Klasse selbst) nochmals 1:1 scrhreiben/kopieren müssen. Dazu erstelle ich eine Klasse die mir das gewünschte interface implementiert und erzeuge diese als property in allen anderen Klassen und übernehme das Interface mit der implements property Klausel....

Anscheinend ist aber etliches unklar darum jetzt ein volles Beipsiel (Klassen wie TTestLabel soll/gibt es dann X mal und brauchen alle die ICommon Interfacemethoden nicht implementieren sondern unterstützen diese automatisch über die implements ICommon):

Code: Alles auswählen

 
unit unit2;
 
interface
 
uses Classes,Controls;
 
type
  ICommon = Interface(IInterface)
      ['{6b10544a-ddb0-43de-9612-348f547110da}']
      function GetTest() : Boolean;
      property Test : Boolean read GetTest;
  end;
 
  TTestLabel = class(TControl,ICommon)
  public
   fCommon : ICommon;
 
   constructor Create(TheOwner: TComponent); override;
   destructor Destroy; override;
 
   function GetTestWrap() : Boolean; //dont want to need this...
 
   // with this line the Interface gets directed to fCommon
   // and i dont need to implement the Interface myself
   property CommonInterface : ICommon read fCommon implements ICommon;
  published
  // property Test;  // not working...
  // property Test : Boolean read GetTest write SetTest default False; // not working
  // property Test : Boolean read fCommon.GetTest write fCommon.SetTest default False; // not working
  // property Test : Boolean read ICommon.GetTest write ICommon.SetTest default False; // not working
    property Test : Boolean read GetTestWrap ; // working but more code..
  end;
 
  // This class implements ICommon and will be uses in many other classes like TTestLabel above
  // So not all classes have to implement/write the full interface functions....
  TCommonImplementer= class(TComponent,ICommon)
    function GetTest() : Boolean;
  end;
 
implementation
 
function TCommonImplementer.GetTest() : Boolean;
begin
  Result:=True;
end;
 
constructor TTestLabel.Create(TheOwner: TComponent);
begin
  inherited;
 
  fCommon:=TCommonImplementer.Create(Self);
end;
 
function TTestLabel.GetTestWrap() : Boolean; // dont want to write wrappers for each function...
begin
  Result:=fCommon.GetTest(); // just wrap interface function...
end;
 
destructor TTestLabel.Destroy;
begin
  fCommon:=nil// fCommon gets freed over (Self) owner on create, but need to
                        // set this pointer to nil to get internal RefCounter down to prevent
                 // segfault (mostly on windows)
  inherited;
end;
 
var
  TestLabel : TTestLabel;
  Test : Boolean;
initialization
 
  TestLabel:=TTestLabel.Create(nil);
   Test:=TestLabel.Test; // this calls TTestLabel.GetTestWrap->TCommonImplementer.GetTest
                                   // but should call more directly TCommonImplementer.GetTest
  TestLabel.Free;
end.
 

SchwabenTom
Beiträge: 49
Registriert: So 4. Jan 2015, 21:34
OS, Lazarus, FPC: Winux (L 0.9.xy FPC 2.2.z)
CPU-Target: xxBit

Re: Published property getter/setter dirüber implements prop

Beitrag von SchwabenTom »

Code: Alles auswählen

 
type
  ICommon = Interface(IInterface)
      ['{6b10544a-ddb0-43de-9612-348f547110da}']
  public       //  kann es sein, daß da nur ein public fehlt?
      function GetTest() : Boolean;
      property Test : Boolean read GetTest;
  end;
 


Kann es sein, daß da nur ein public fehlt?
Sind die Member ohne Angabe per default protected?

Benutzeravatar
m.fuchs
Lazarusforum e. V.
Beiträge: 2640
Registriert: Fr 22. Sep 2006, 19:32
OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
CPU-Target: x86, x64, arm
Wohnort: Berlin
Kontaktdaten:

Re: Published property getter/setter dirüber implements prop

Beitrag von m.fuchs »

SchwabenTom hat geschrieben:Kann es sein, daß da nur ein public fehlt?
Sind die Member ohne Angabe per default protected?

Nein, im Interface ist per Definition alles public. Anders geht es gar nicht und daher fehlt das public nicht, es würde sogar einen Fehler darstellen.
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de

Antworten