Properties in Interfaces

Mitteilungen und Ankündigungen

Properties in Interfaces

Beitragvon braunbär » 6. Okt 2018, 18:48 Properties in Interfaces

Ich habe eine Weile herumprobiert, aber ich habe das Gefühl, die funktionieren überhaupt nicht (oder ich mach was falsch, bloss keine Ahnung was). Jeder Versuch, auf Interfacevariable.Property zuzugreifen, wird vom Compiler mit einer Fehlermeldung (cannot access... oder so ähnlich) quittiert.
Als workaround habe ich jetzt die Getter und Setter Methoden ins Interface genommen und in der Komponente public gemacht und die Property rausgeschmissen, das geht dann problemlos.
Hat jemand einen Link auf ein funktionierendes Beispiel für eine Property in einem Interface?
braunbär
 
Beiträge: 255
Registriert: 8. Jun 2017, 17:21

Beitragvon Mathias » 6. Okt 2018, 18:54 Re: Properties in Interfaces

Kannst du mal ein Beispiel posten, welches nicht geht ?
Dann sieht man am ehesten, wo du einen Fehler machst.

Hier hast du was ähnliches gefragt. viewtopic.php?f=5&t=11824
Mit Lazarus sehe ich gün
Mit Java und C/C++ sehe ich rot
Mathias
 
Beiträge: 4342
Registriert: 2. Jan 2014, 17:21
Wohnort: Schweiz
OS, Lazarus, FPC: Linux (die neusten Trunc) | 
CPU-Target: 64Bit
Nach oben

Beitragvon braunbär » 6. Okt 2018, 20:16 Re: Properties in Interfaces

Oje, ich sehe gerade, ich habe das in einem ganz falschen Unterforum gepostet, sorry.

Mathias hat geschrieben:Hier hast du was ähnliches gefragt.

Eigentlich nicht. Das dort hat mit dieser Frage gar nichts zu tun. Dort ging es um automatische Quelltextvervollständigung.

Mathias hat geschrieben:Kannst du mal ein Beispiel posten, welches nicht geht ?

Hmm, ich habe fast gewusst, dass die Frage kommen wird. Ich habe blöderweise das ganze schon auf getter und setter im Interface geändert, da funktioniert es, und mir den Code von vorher nicht aufgehoben. Mit einem Link auf ein funktionierendes Beispiel würde ich wahrscheinlich sebst sehen, was ich falsch gemacht habe, deshalb erst einmal die Frage danach. Ich habe so ein Codebeispiel gesucht, aber nichts gefunden. In den Tutorials kommen keine Properties vor. Wenn niemand so was hat, spiele ich mich noch einmal damit, das Problem auf einen Minimalcode herunterzubrechen, der nicht funktioniert, und poste den dann hier.

Dass Properties nicht verwendet werden können, wenn das Interface mit externen nicht-Lazarus Programmen verwendet wird, steht in der Dokumentation. Aber bei mir handelt es sich um ein Interface, das nur programmintern verwendet wird. Das sollte ja funktionieren.
braunbär
 
Beiträge: 255
Registriert: 8. Jun 2017, 17:21

Beitragvon Mathias » 6. Okt 2018, 22:13 Re: Properties in Interfaces

Hast du mal im wiki unter property geguckt ?
Mit Lazarus sehe ich gün
Mit Java und C/C++ sehe ich rot
Mathias
 
Beiträge: 4342
Registriert: 2. Jan 2014, 17:21
Wohnort: Schweiz
OS, Lazarus, FPC: Linux (die neusten Trunc) | 
CPU-Target: 64Bit
Nach oben

Beitragvon braunbär » 6. Okt 2018, 22:41 Re: Properties in Interfaces

Wenn da etwas zu properties in Interfaces steht, dann bin ich bei meiner Suche nicht darauf gestossen. Hast du einen Link?
braunbär
 
Beiträge: 255
Registriert: 8. Jun 2017, 17:21

Beitragvon Mathias » 7. Okt 2018, 16:23 Re: Properties in Interfaces

Hast du einen Link?
http://wiki.freepascal.org/Property/de

Ich verstehe dich nicht ganz, was du mit interfaces meinst. Eine property wird immer in einer Class deklariert.
Die property befindet sich dabei im public-Teil.
Die Setter und Getter und auch die interne Variable befinden sich dann im private-Teil.
Mit Lazarus sehe ich gün
Mit Java und C/C++ sehe ich rot
Mathias
 
Beiträge: 4342
Registriert: 2. Jan 2014, 17:21
Wohnort: Schweiz
OS, Lazarus, FPC: Linux (die neusten Trunc) | 
CPU-Target: 64Bit
Nach oben

Beitragvon wp_xyz » 7. Okt 2018, 16:41 Re: Properties in Interfaces

braunbär hat geschrieben:Als workaround habe ich jetzt die Getter und Setter Methoden ins Interface genommen und in der Komponente public gemacht und die Property rausgeschmissen, das geht dann problemlos.
Hat jemand einen Link auf ein funktionierendes Beispiel für eine Property in einem Interface?

Im Interface IChartDrawer, das Alexander Kleinen für TAChart geschrieben hat, gibt es Properties (unit TADrawUtils):
Code: Alles auswählen
  IChartDrawer = interface
    ['{6D8E5591-6788-4D2D-9FE6-596D5157C3C3}']
    procedure AddToFontOrientation(ADelta: Integer);
    procedure ClippingStart(const AClipRect: TRect);
    procedure ClippingStart;
    procedure ClippingStop;
    procedure DrawingBegin(const ABoundingBox: TRect);
    procedure DrawingEnd;
    procedure DrawLineDepth(AX1, AY1, AX2, AY2, ADepth: Integer);
    procedure DrawLineDepth(const AP1, AP2: TPoint; ADepth: Integer);
    procedure Ellipse(AX1, AY1, AX2, AY2: Integer);
    procedure FillRect(AX1, AY1, AX2, AY2: Integer);
    function GetBrushColor: TChartColor;
    function GetFontAngle: Double;       // in radians
    function GetFontColor: TFPColor;
    function GetFontName: String;
    function GetFontSize: Integer;
    function GetFontStyle: TChartFontStyles;
    procedure SetDoChartColorToFPColorFunc(AValue: TChartColorToFPColorFunc);
    procedure Line(AX1, AY1, AX2, AY2: Integer);
    procedure Line(const AP1, AP2: TPoint);
    procedure LineTo(AX, AY: Integer);
    procedure LineTo(const AP: TPoint);
    procedure MoveTo(AX, AY: Integer);
    procedure MoveTo(const AP: TPoint);
    procedure Polygon(
      const APoints: array of TPoint; AStartIndex, ANumPts: Integer);
    procedure Polyline(
      const APoints: array of TPoint; AStartIndex, ANumPts: Integer);
    procedure PrepareSimplePen(AColor: TChartColor);
    procedure PutImage(AX, AY: Integer; AImage: TFPCustomImage);
    procedure PutPixel(AX, AY: Integer; AColor: TChartColor);
    procedure RadialPie(
      AX1, AY1, AX2, AY2: Integer;
      AStartAngle16Deg, AAngleLength16Deg: Integer);
    procedure Rectangle(const ARect: TRect);
    procedure Rectangle(AX1, AY1, AX2, AY2: Integer);
    procedure ResetFont;
    function Scale(ADistance: Integer): Integer;
    procedure SetAntialiasingMode(AValue: TChartAntialiasingMode);
    procedure SetBrushColor(AColor: TChartColor);
    procedure SetBrush(ABrush: TFPCustomBrush);
    procedure SetBrushParams(AStyle: TFPBrushStyle; AColor: TChartColor);
    procedure SetFont(AValue: TFPCustomFont);
    procedure SetGetFontOrientationFunc(AValue: TGetFontOrientationFunc);
    procedure SetMonochromeColor(AColor: TChartColor);
    procedure SetPen(APen: TFPCustomPen);
    procedure SetPenParams(AStyle: TFPPenStyle; AColor: TChartColor);
    function GetRightToLeft: Boolean;
    procedure SetRightToLeft(AValue: Boolean);
    procedure SetTransparency(ATransparency: TChartTransparency);
    procedure SetXor(AXor: Boolean);
    function TextExtent(const AText: String;
      ATextFormat: TChartTextFormat = tfNormal): TPoint;
    function TextExtent(AText: TStrings;
      ATextFormat: TChartTextFormat = tfNormal): TPoint;
    function TextOut: TChartTextOut;
 
    property Brush: TFPCustomBrush write SetBrush;
    property BrushColor: TChartColor read GetBrushColor write SetBrushColor;
    property Font: TFPCustomFont write SetFont;
    property Pen: TFPCustomPen write SetPen;
    property DoChartColorToFPColor: TChartColorToFPColorFunc
      write SetDoChartColorToFPColorFunc;
    property DoGetFontOrientation: TGetFontOrientationFunc
      write SetGetFontOrientationFunc;
  end;

Allerdings kann ich nicht sagen, warum er nur den Setter verwendet hat. Auf jeden Fall ist dieser öffentlicher Bestandteil des Interface, anders kann es ja auch nicht funktionieren, da ein Interface keine eigenen Daten hat.
wp_xyz
 
Beiträge: 2696
Registriert: 8. Apr 2011, 08:01

Beitragvon Mathias » 7. Okt 2018, 16:54 Re: Properties in Interfaces

Jetzt weis ich, was Braunbär mit interface meint. Ich dachte, er meinte das interface oben bei einer Unit.
Mit Lazarus sehe ich gün
Mit Java und C/C++ sehe ich rot
Mathias
 
Beiträge: 4342
Registriert: 2. Jan 2014, 17:21
Wohnort: Schweiz
OS, Lazarus, FPC: Linux (die neusten Trunc) | 
CPU-Target: 64Bit
Nach oben

Beitragvon Socke » 8. Okt 2018, 09:24 Re: Properties in Interfaces

Properties aus Interfaces sind nicht automatisch in der implementierenden Klasse vorhanden. Sie sind mehr oder weniger nur Syntax-Kleber um nicht immer mit den Getter- und Setter-Methoden des Interfaces arbeiten zu müssen.

Code: Alles auswählen
program Project1;
{$Interfaces CORBA}
 
type
  IMyInterface = interface ['{7317CF7F-643D-43DD-B1AB-D1FF75C8859F}']
    function GetMyValue: Integer;
    procedure SetMyValue(AValue: Integer);
    property MyValue: Integer read GetMyValue write SetMyValue;
  end;
 
  TMyClass = class(TObject, IMyInterface)
  strict private
    fMyValue: Integer;
  public
    function GetMyValue: Integer;
    procedure SetMyValue(AValue: Integer);
  end;
 
function TMyClass.GetMyValue: Integer;
begin
  Result := fMyValue;
end;
 
procedure TMyClass.SetMyValue(AValue: Integer);
begin
  fMyValue := AValue;
end;
 
var
  o: TMyClass;
  i: IMyInterface;
begin
  o := TMyClass.Create;
  o.SetMyValue(5);
  i := o;
  WriteLn(i.MyValue);
  i.MyValue := 10;
  WriteLn(i.MyValue);
  // Error: identifier idents no member "MyValue"
  /// o.MyValue := 100;
  o.Destroy;
  ReadLn;
end.


Mathias hat geschrieben:Jetzt weis ich, was Braunbär mit interface meint. Ich dachte, er meinte das interface oben bei einer Unit.

Zur Vollständigkeit: Properties kann man auf überall verwenden, wo sie sinnvoll sind:
  • Klassen
  • Objekte
  • Interfaces
  • Records
  • Type/Class/etc. Helper
  • Units
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein
Socke
 
Beiträge: 2557
Registriert: 22. Jul 2008, 18:27
Wohnort: Köln
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 8.1/Debian GNU/Linux/Raspbian/openSUSE | 
CPU-Target: 32bit x86 armhf
Nach oben

Beitragvon braunbär » 8. Okt 2018, 17:56 Re: Properties in Interfaces

Socke hat geschrieben:Properties aus Interfaces sind nicht automatisch in der implementierenden Klasse vorhanden. Sie sind mehr oder weniger nur Syntax-Kleber um nicht immer mit den Getter- und Setter-Methoden des Interfaces arbeiten zu müssen.

Ok, dann (und mit dem beispiel von wp_xyz) ist mir klar, was bei mir falsch war. Das bedeutet aber auch, dass man bei einer Klasse, die eine Interface-Property implementiert, sowohl getter wie setter für die Property braucht, read Fxxxx und write Fxxxx geht dann nicht, weil die Variable Fxxxx kann im Interface natürlich nicht deklariert werden.
braunbär
 
Beiträge: 255
Registriert: 8. Jun 2017, 17:21

Beitragvon m.fuchs » 9. Okt 2018, 10:24 Re: Properties in Interfaces

braunbär hat geschrieben:Das bedeutet aber auch, dass man bei einer Klasse, die eine Interface-Property implementiert, sowohl getter wie setter für die Property braucht, read Fxxxx und write Fxxxx geht dann nicht, weil die Variable Fxxxx kann im Interface natürlich nicht deklariert werden.

Ja, das ist leider eine Schwäche des Pascal-Interfacekonzeptes. Besser wäre es wenn ich im Interface nur eine Property fordere:

Code: Alles auswählen
type
  IMyInterface = interface
    property MyString: String;
  end;


Und dann kann jeder Entwickler selber entscheiden, wie er diese implementiert:

Code: Alles auswählen
type
  TMyClass = class(TObject, IMyInterface)
    private
      FMyString: String;
    public
      property MyString read FMyString write FMyString;
  end;


Mann bräuchte dann noch einen Modifier für das Interface um auf Read- und WriteOnly-Properties hinzuweisen. Wäre so dann aus meiner Sicht flexibler.
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de
m.fuchs
 
Beiträge: 1972
Registriert: 22. Sep 2006, 18:32
Wohnort: Berlin
OS, Lazarus, FPC: Winux (L 1.8.4, FPC 3.0.4) | 
CPU-Target: x86, x64, arm
Nach oben

Beitragvon Socke » 9. Okt 2018, 10:52 Re: Properties in Interfaces

m.fuchs hat geschrieben:Ja, das ist leider eine Schwäche des Pascal-Interfacekonzeptes. Besser wäre es wenn ich im Interface nur eine Property fordere:

Du musst dann immer noch Methoden definieren, mit denen auf die Properties zugegriffen werden kann. Ansonsten hast du Properties, die du aussschließlich in der Klasse verwenden kannst, die das Interface implementiert, da anderswo gar nicht bekannt ist, wie das Property verarbeitet wird.
Hast du beispielsweise ein öffentliches Interface (Interface-Abschnitt der Unit), die implementierende Klasse ist aber nur im Implementation-Abschnitt definiert, hast du von anderen Units aus nicht einmal die Klassendefinition.
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein
Socke
 
Beiträge: 2557
Registriert: 22. Jul 2008, 18:27
Wohnort: Köln
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 8.1/Debian GNU/Linux/Raspbian/openSUSE | 
CPU-Target: 32bit x86 armhf
Nach oben

Beitragvon m.fuchs » 9. Okt 2018, 13:10 Re: Properties in Interfaces

Socke hat geschrieben:Du musst dann immer noch Methoden definieren, mit denen auf die Properties zugegriffen werden kann. Ansonsten hast du Properties, die du aussschließlich in der Klasse verwenden kannst, die das Interface implementiert, da anderswo gar nicht bekannt ist, wie das Property verarbeitet wird.

Das ist ja grundsätzlich unwichtig, wie die Verarbeitung erfolgt. Also aus abstrakter Sicht. Das es in Pascal technisch nicht geht, weil Properties nur syntaktischer Zucker sind und den Zugriff auf Getter und Setter ein bisschen verstecken ist ja dann die Realität.
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de
m.fuchs
 
Beiträge: 1972
Registriert: 22. Sep 2006, 18:32
Wohnort: Berlin
OS, Lazarus, FPC: Winux (L 1.8.4, FPC 3.0.4) | 
CPU-Target: x86, x64, arm
Nach oben

Beitragvon Socke » 9. Okt 2018, 13:16 Re: Properties in Interfaces

m.fuchs hat geschrieben:
Socke hat geschrieben:Du musst dann immer noch Methoden definieren, mit denen auf die Properties zugegriffen werden kann. Ansonsten hast du Properties, die du aussschließlich in der Klasse verwenden kannst, die das Interface implementiert, da anderswo gar nicht bekannt ist, wie das Property verarbeitet wird.

Das ist ja grundsätzlich unwichtig, wie die Verarbeitung erfolgt. Also aus abstrakter Sicht. Das es in Pascal technisch nicht geht, weil Properties nur syntaktischer Zucker sind und den Zugriff auf Getter und Setter ein bisschen verstecken ist ja dann die Realität.

Man könnte diese Compiler-Magie durchaus implementieren, dann hat man aber plötzlich Properties, auf die man in Fremdbibliotheken gar nicht - nicht einmal über die Getter- und Setter-Methoden zugreifen kann. Damit ist die Interoperabilität, die man durch Interfaces gewonnen hat, nicht mehr gegeben.
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein
Socke
 
Beiträge: 2557
Registriert: 22. Jul 2008, 18:27
Wohnort: Köln
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 8.1/Debian GNU/Linux/Raspbian/openSUSE | 
CPU-Target: 32bit x86 armhf
Nach oben

Beitragvon af0815 » 9. Okt 2018, 14:55 Re: Properties in Interfaces

BTW: Properties und Lazarus

Aktuell mit Problemen rechnen, wenn man Properties auf published setzt und das ganze in einer visuellen Komponente hat. Da hat es mit Lazarus Probleme gegeben. Dazu gabs hier im Forum und im englischen Forum Diskussionen, Bugfixes und 'Best practice'
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).
af0815
 
Beiträge: 3501
Registriert: 7. Jan 2007, 10:20
Wohnort: Niederösterreich
OS, Lazarus, FPC: FPC 3.2 Lazarus 2.0 per fpcupdeluxe | 
CPU-Target: 32Bit (64Bit)
Nach oben

• Themenende •

Zurück zu Ankündigungen



Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 2 Gäste

porpoises-institution
accuracy-worried