Delphi-PRAXiS
Seite 5 von 5   « Erste     345   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi Basisklasse und davon abgeleitet drei Standardklassen (https://www.delphipraxis.net/101105-basisklasse-und-davon-abgeleitet-drei-standardklassen.html)

Jens Schumann 9. Okt 2007 19:04

Re: Basisklasse und davon abgeleitet drei Standardklassen
 
Hallo,
die Lösung mit den Interfaces ist sehr interessant. Das Edit, Memo usw. habe ich mal als Parent des Interfaces
betrachtet und in die Interfacedeklaration gezogen. Ebenso eine neue Eigenschaft (Size) über das Interface
angegeben. Wenn die verschiedenen Klassen eine gemeinsane property wie Text oder so haben kann man die
Eigenschaft ebenfalls ins Interface schieben. Dann der Zugriff auf diese Eigenschaft direkt über das Interface erfolgen.

Delphi-Quellcode:
var
 
  MyEdit : IMyInterface; // Als IMyInterface deklariert !!!
...

  MyEdit:=TMyEdit.Create(Owner);
...
 
  MyEdit.Text:='Juhu';
Delphi-Quellcode:
unit Unit2;

interface

uses SysUtils, classes, StdCtrls;

Type

  IMyInterface=interface(IInterface)
  ['{D3A9F1B4-E566-4568-A3DC-9FDA533452E0}']
    function GetSize : Integer;
    procedure SetSize(Value : Integer);
    function GetParent : TObject;
    procedure SetParent(Value : TObject);
    function GetText : String;
    procedure SetText(Value : String);
    property Parent : TObject read GetParent write SetParent;
    property Size : Integer read GetSize write SetSize;
    property Text : String read GetText write SetText;
  end;

  //Helperklasse für das Interface. Diese weiss, was zu tun ist, wenn die Methoden gerufen werden
  TMyIntfHelper=Class(TObject)
  private
    FParent : TObject;
    FSize  : Integer;
  public
    function GetSize : Integer;
    procedure SetSize(Value : Integer);
    function GetParent : TObject;
    procedure SetParent(Value : TObject);
    function GetText : String;
    procedure SetText(Value : String);
    property Parent : TObject read GetParent write SetParent;
    property Size  : Integer read GetSize write SetSize;
    property Text  : String read GetText write SetText;
  end;


  TMyEdit = class(TEdit,IMyInterface)
  private
    FHelper: TMyIntfHelper;
  public
    constructor Create(AOwner : TComponent); override;
    destructor Destroy; override;
    property MyHelper: TMyIntfHelper Read FHelper implements IMyInterface;
  end;

implementation


{ TMyEdit }

constructor TMyEdit.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  FHelper:=TMyIntfHelper.Create;
  FHelper.Parent:=Self;
end;

destructor TMyEdit.Destroy;
begin
  FHelper.Free;
  inherited Destroy;
end;

{ TMyIntfHelper }

function TMyIntfHelper.GetParent: TObject;
begin
  Result:=FParent;
end;

function TMyIntfHelper.GetSize: Integer;
begin
  Result:=FSize;
end;

function TMyIntfHelper.GetText: String;
begin
  If FParent is TEdit then // müsste entsprechend auf TMemo oder TStrings etc erweitert werden. evt kann man auch über RTTI feststellen ob die Eigenschaft vorhanden ist
    Result:=(FParent as TEdit).Text
      else
        Result:='';
end;

procedure TMyIntfHelper.SetParent(Value: TObject);
begin
  FParent:=Value;
end;

procedure TMyIntfHelper.SetSize(Value: Integer);
begin
  FSize:=Value;
end;


procedure TMyIntfHelper.SetText(Value: String);
begin
  If FParent is TEdit then
    (FParent as TEdit).Text:=Value;
end;

end.
@ Sidorion: Coole Lösung !!!

@shmia: Dein Vorschlag mit MVC Pattern funktioniert doch nur wenn man Herr der Objekthiearchie ist. Was ist wenn Du Klassen verwenden musst deren Sourcecode Du nicht hast?

s-off 9. Okt 2007 20:51

Re: Basisklasse und davon abgeleitet drei Standardklassen
 
Liste der Anhänge anzeigen (Anzahl: 1)
So, der Beitrag von Jens Schumann hat mir den letzten Schwung gegeben - ich habe es - denke ich zumindest - hinbekommen. Das Control wird inkl. der Schrift nun gezoomt, sobald der Wert des SpinEdits geändert wird - und das war es, was ich erreichen wollte.

Ich danke allen, die mich durch Ihre Beiträge zur Lösung geschleppt haben :zwinker:

PS: das Projekt ist angehängt - da kann man sicherlich noch vieles verändern/-bessern. Aber die Funktionalität an sich ist ersteinmal gegeben.

Fraglich ist halt, ob sich der Aufwand bei diesem 'Pipi-Fall' lohnt. Aber interessant ist es in jedem Fall!


Danke nochmal an alle :thumb: :hello:

Sidorion 10. Okt 2007 08:29

Re: Basisklasse und davon abgeleitet drei Standardklassen
 
Es gibt keine Pipi-Fälle. Durch diesen hast Du ja immerhin etwas grundlegend neues dazugelernt.

s-off 10. Okt 2007 08:44

Re: Basisklasse und davon abgeleitet drei Standardklassen
 
Zitat:

Zitat von Sidorion
Es gibt keine Pipi-Fälle. Durch diesen hast Du ja immerhin etwas grundlegend neues dazugelernt.

Upsi - dann habe ich mich wohl etwas falsch ausgedrückt. :?
Die Bezeichnung 'Pipi-Fall' bezog sich auf das Ausgangsproblem, nicht auf die Lösung (hier: Interfaces) :!: .

Ich freue mich natürlich immer sehr, wenn ich etwas neues dazu lerne - ob das nun etwas essentiell wichtiges ist, oder nicht, spielt keine Rolle. Irgendwann kann man alles irgendwie irgendwo gebrauchen.

Und gerade diese Lösung finde ich sehr interessant, da sie u.a. das 'Problem' der nicht vorhandenen Mehrfachvererbung umgeht.

Tschuldigung, wenn das falsch rübergekommen sein sollte :(

Sidorion 10. Okt 2007 09:39

Re: Basisklasse und davon abgeleitet drei Standardklassen
 
Da hab ich mich jetzt wohl etwas unverständlich ausgedrückt. Ich wollte Dich nicht kritisieren oder so. Dein Beispiel für die DP hier mag etwas simpel rüberkommen, aber es ging ja ums Prinzip und da nimmt man halt besser ein kleines Beispiel. Ausserdem ist dieses Problem keinesfalls trivial, egal wie simpel es zunächst aussehen mag.
Man hätte das auch mit einem Container lösen können (hab ich mal gemacht, ich brauchte verschiedene WinControls mit links nem label dran usw. Da wurde dann ein Panel mit dem Control und nem Label draus), das wäre aber wesentlich aufwändiger geworden. Sprich: Die Basisklasse 'kennt' das Control, das sie kontrollieren kann (aber eben nur als TWinControl) und die Ableitungen instanzieren dann jeweils ein edit oder label oder...

guidok 10. Okt 2007 09:59

Re: Basisklasse und davon abgeleitet drei Standardklassen
 
Vielleicht kannst du ja sowas machen:

Delphi-Quellcode:
Type
   TExtra = class
      FWind: String;
      FEigenschaft1: Integer;
      FEigenschaft2: Integer;
      FEigenschaft3: Integer;
      Procedure SetWind(Const Value: Integer);
   public
       Property Wind: String read FWind write SetWind;
   End;

   TEditklasse = Class(TEdit)
   private
      FExtra: TExtra;
   public
       Property Extra: String read FExtra write FExtra;
   End;

   TLabelklasse = class(TLabel)
       FExtra: TExtra;
   public
       Property Extra: String read FExtra write FExtra;
   end;

   TMemoklasse = Class(TMemo)
       FExtra: TExtra;
   public
       Property Extra: String read FExtra write FExtra;
   End;

s-off 10. Okt 2007 10:08

Re: Basisklasse und davon abgeleitet drei Standardklassen
 
Zitat:

Zitat von Sidorion
Da hab ich mich jetzt wohl etwas unverständlich ausgedrückt.

Ok, dann haben wir das ja jetzt geklärt :wink: - vielen dank nochmal :-D

Zitat:

Zitat von guidok
Vielleicht kannst du ja sowas machen: [...]

Als ich das Beispiel mit den Interfaces lauffähig bekommen habe, dachte ich ehrlich gesagt genau das Gleiche.
Warum den abgeleiteten Standardcontrols nicht eine zusätzliche Eigenschaft in Form eines Objektes der zusätzlichen Klasse verpassen.

Ob es im Endeffekt genauso funktioniert, wie erwartet - also so wie die Interface-Geschichte - , habe ich schlussendlich allerdings nicht mehr getestet. Könnte man aber nochmal machen :zwinker:

Edit: ok, habe es nun getestet - funktioniert ohne Interface genauso wie mit.
Mit dem einen Unterschied, dass ich dann beim Aufruf nicht caste, sondern über die Property gehe.

Delphi-Quellcode:
   TEditklasse = Class(TEdit)
   private
      FHelper: TBasisklasse;
   public
      Constructor Create(AOwner: TComponent); override;
      Property MyHelper: TBasisklasse read FHelper write FHelper;
   End;

   Constructor TEditklasse.Create(AOwner: TComponent);
   Begin
      Inherited;
      FHelper := TBasisklasse.Create(Self);
      Parent := TWinControl(AOwner);
   End;

   oEdit := TEditklasse.Create(Self);
   oEdit.MyHelper.Zoom(SpinEdit1.Value);
Und das ist dann wohl genau das, was Jelly vorgestern schon mit
Zitat:

Zitat von Jelly
Es bleibt dir wohl nichts anderes übrig, als 3 neue Unterklassen von TEdit, TMemo und TLabel zu erstellen, und dort jeweils als Referenz auf deine TBasisklasse zu referieren (Assoziation im UML Jargon)

und Hansa mit
Zitat:

Zitat von Hansa
Du wärst schon lange fertig, wenn die 3 Komponenten jeweils eine property mehr hätten.

meinten.

Habe mir mal die Modellansicht zu dem Projekt angeschaut, und siehe da:
Zitat:

Assoziationsbeziehung

zu Klasse TBasisklasse

Supplier
TBasisklasse

Client
FHelper

Type
Assoziation
Verrückte Welt :stupid:

Sidorion 10. Okt 2007 11:20

Re: Basisklasse und davon abgeleitet drei Standardklassen
 
So musst Du aber immer den genauen Typ kennen. TMyEdit kannst Du nicht als TMyLabel ansprechen usw., da ja die Basisklasse fehlt (sie haben keinen gemeinsamen Nenner). Sprich Du kannst Deine Elemente nicht in eine Liste packen (ausser als Controls vielleicht) und musst immer mit Is fragen, welches es ist (bei TMyEdit-Instanz in variable geht eben nicht TMylabel(variable).Property, wegen der anderen vmt). Damit bist Du nicht erweiterungsfähig. Wenn eine Neue Klasse dazukommt, musst Du den Code umschreiben, der diese Klassen benutzt und das widerspricht dem Sinn der Objektorientierung.
Mit dem Interface hast Du ein z.B. Array of IMyInterface oder TInterfaceList und kannst alle ansprechen, ohne auf die eigentliche Natur der Elemente rücksicht nehmen zu müssen. Zudem kannst Du hier einfach einen TMyButton mit diesem Interface neu erfinden und ohne weiteres in dieses Array stecken.

s-off 10. Okt 2007 11:52

Re: Basisklasse und davon abgeleitet drei Standardklassen
 
Zitat:

Zitat von Sidorion
Damit bist Du nicht erweiterungsfähig.

Stimmt, aus Sicht der Dynamik sind die Interfaces sicherlich sinnvoll.

Aber in meinem speziellen Fall, in dem ich nur auf Eigenschaften zugreife, über die alle benutzten Klassen verfügen, wäre dieses Assoziieren doch denkbar.

Naja, wie dem auch sei :-D


Alle Zeitangaben in WEZ +1. Es ist jetzt 13:07 Uhr.
Seite 5 von 5   « Erste     345   

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz