Delphi-PRAXiS
Seite 3 von 5     123 45      

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)

s-off 8. Okt 2007 21:06

Re: Basisklasse und davon abgeleitet drei Standardklassen
 
Zitat:

Zitat von Hansa
Hier steht nicht viel brauchbares !

Das mag wohl sein. Wenn ich etwas brauchbares anzubieten hätte, müsste ich hier nicht um Hilfe bitten.

Zitat:

Zitat von Hansa
Das einzige wäre ein Tedit und ein TMemo. Die besitzen zumindest mal Editier-Funktionalitäten. Ein TLabel hat nicht mal die. Wozu soll dieser unzusammenhängende Kram jetzt zusammengeschmissen werden ?

Diese drei Standardklassen sind Beispiele. Es ist dabei vollkommen egal, was die können, ob sie eine Editiermöglichkeit bieten, oder sonstetwas.

:!:
Vielleicht ein kurzer Satz zur Erläuterung.
Seitens meines Arbeitgebers bin ich sehr eingeschränkt, was die Herausgabe von Informationen betrifft.
Ich darf mich zwar hier im Forum aufhalten, darf auch Fragen stellen und Antworten geben - ich darf allerdings keinerlei Originalquellcode - und seien es nur Variablennamen - veröffentlichen, der in irgendeinem Zusammenhang mit unserem Projekt steht; dafür musste ich sogar unterschreiben.

Über Sinn und Unsinn dieser Richtlinie kann man streiten - möchte ich aber nicht, da ich - und auch niemand anderes - etwas daran ändern kann.

Aus diesem Grund muss ich alles, was ich hier reinposte, irgendwie abstrahieren - dabei kommt dann gelegentlich auch etwas zusammenhangloses Zeugs heraus.

Daher habe ich - so dachte ich zumindest - eindeutig geschildert, was ich haben möchte.
Da das anscheinend nicht der Fall ist, versuche ich es nocheinmal.

Ich muss dynamisch verschiedene Controls erzeugen. Nehmen wir beispielsweise(!) TEdit, TCheckbox und TComboBox.
Alle diese drei Controls müssen mit einer zusätzlichen Funktionalität ausgestattet werden. Nennen wir diese Funktionalität 'Sag mir Deinen Startwert' (nur als Beispiel!).
So, alle diese Controls werden mit einem Startwert (Text, Checked, Text) belegt.
Dieser kann zur Laufzeit geändert werden.
Irgendwann sollen mir diese Controls auf Zuruf ihren Startwert mitteilen.

Ich erzeuge mir also für alle 3 Controls eine eigene Klasse.
Diese Klasse bekommt ein Feld FStartwert. In diesem wird der Initialwert gespeichert, sobald das Objekt erzeugt worden ist.
Jetzt gibt es zusätzlich die Public-Funktion 'GibStartwert'. Diese malt dem Startwert (FStartwert) ein paar Blümchen aufs Hemd und gibt ihn in einer Message aus. Fertig.

So, jetzt kann ich allen diesen 3 abgeleiteten Klassen (TMeinEdit, TMeineCheckbox und TMeine ComboBox) das Feld FStartwert und die Methode GibStartwert geben.
Bei allen sähe die Methode GibStartwert gleich aus.

Müsste ich nun an dieser Methode etwas ändern, so müsste ich das in allen drei Klassen tun.

Und das ist der Knackpunkt, wo ich denke, dass das aus Sicht der OOP nicht so günstig ist.

Also dachte ich mir - erzeuge ich mir eine Basisklasse, die das Feld FStartwert und die Methode GibStartwert hat, und leite dann meine 3 Controls davon ab - naja, den Rest kennt ihr ja.

Ich hoffe, dass mein Vorhaben - auch wenn es wieder abstrahiert ist - etwas deutlicher wurde.

Dax 8. Okt 2007 21:16

Re: Basisklasse und davon abgeleitet drei Standardklassen
 
Delphi-Quellcode:
type
  IStartwert = interface
    function GibStartwert: string;
  end;

  TStartwert = class(TInterfacedObject, IStartwert)
  private
    fStartwert: string;
  public
    function GibStartwert: string;

    constructor Create(startwert: string);
  end;

  TEditEx = class(TEdit, IStartwert)
  private
    fStartwert: TStartwert;
  public
    property Startwert: IStartwert read fStartwert implements IStartwert;

    constructor Create;
  end;


function TStartwert.GibStartwert: string;
begin
  Result := fStartwert;
end;

constructor TStartwert.Create(startwert: string);
begin
  inherited Create;
  fStartwert := startwert;
end;

constructor TEditEx.Create;
begin
  inherited Create;
  fStartwert := TStartwert.Create('blubb');
end;
Ich weiß nicht, ob es direkt kopiert so funktioniert (hab kein Delphi, es zu testen), aber im Prinzip dürfte das doch deinen Anforderungen entsprechen..?

Hansa 8. Okt 2007 21:26

Re: Basisklasse und davon abgeleitet drei Standardklassen
 
Zitat:

Zitat von s-off
...Ich erzeuge mir also für alle 3 Controls eine eigene Klasse.
Diese Klasse bekommt ein Feld FStartwert. In diesem wird der Initialwert gespeichert, sobald das Objekt erzeugt worden ist.
Jetzt gibt es zusätzlich die Public-Funktion 'GibStartwert'. Diese malt dem Startwert (FStartwert) ein paar Blümchen aufs Hemd und gibt ihn in einer Message aus. Fertig.

So, jetzt kann ich allen diesen 3 abgeleiteten Klassen (TMeinEdit, TMeineCheckbox und TMeine ComboBox) das Feld FStartwert und die Methode GibStartwert geben.
Bei allen sähe die Methode GibStartwert gleich aus.

Müsste ich nun an dieser Methode etwas ändern, so müsste ich das in allen drei Klassen tun.

Und das ist der Knackpunkt, wo ich denke, dass das aus Sicht der OOP nicht so günstig ist.
..

Du wärst schon lange fertig, wenn die 3 Komponenten jeweils eine property mehr hätten. Benutze besser diese drei, als eine letztenendes unbrauchbare Hyperklasse zu machen. Und den Ober-Aufsehern würde ich mal sagen, dass sie übertreiben (Variablennamen ? :shock: ) und dadurch kontraproduktiv sind. Ich lasse teilweise bewusst Quelltexte vor Ort. Wer will denn damit was anfangen ? Irgenswo steht in der uses immer eine Unit, die nicht da ist und die sind dann trotz guter Kommentierung völlig am Ende. :mrgreen:

s-off 8. Okt 2007 21:51

Re: Basisklasse und davon abgeleitet drei Standardklassen
 
@Dax:
Prinzipiell ist erfüllt es seinen Dienst, ja.
Aber: da hat dann ja jede Klasse ein Feld und eine zusätzliche Property die ich explizit in der Klasse angeben muss.
Ich weiss, dass ist - ähm - Kleinscheisserei, aber wenn es nur so geht - dann geht es halt nur so - danke :zwinker:
Zu den Helferklassen komm eich gleich.

@Hansa:
Ja, eine zusätzliche Property - das war ja halt die Frage, ob OOP nicht minimalistisch arbeitet; aber anscheinend ja nicht.
Den Ober-Häuptlingen kann man leider nicht reinreden.

@Apollonius, Jens Schumann und Dax:
Helferklassen helfen hier tatsächlich. Und es können sogar Klassenfelder erzeugt werden :-D
Das Ganze sieht dann so aus (wieder abstrahiert):
Delphi-Quellcode:
   TMyEdit = Class(TEdit)
   public
      Constructor Create(AOwner: TComponent); override;
   End;

   TMyClassHelper = Class helper For TMyEdit
   Class Var
         FStartwert: String;
         Procedure GibStartwert(_sPrefix: String);
      End;

Hawkeye219 8. Okt 2007 22:12

Re: Basisklasse und davon abgeleitet drei Standardklassen
 
Hallo,
Zitat:

Zitat von s-off
Und es können sogar Klassenfelder erzeugt werden

Dir ist aber schon klar, daß sich alle Instanzen ein einziges Klassenfeld teilen, oder? Mit anderen Worten: du kannst in dem Feld nicht für jede Instanz einen anderen Wert ablegen.

Gruß Hawkeye

s-off 9. Okt 2007 06:13

Re: Basisklasse und davon abgeleitet drei Standardklassen
 
Guten Morgen.
Zitat:

Zitat von Hawkeye219
Dir ist aber schon klar, daß sich alle Instanzen ein einziges Klassenfeld teilen, oder? Mit anderen Worten: du kannst in dem Feld nicht für jede Instanz einen anderen Wert ablegen.

Danke für den Hinweis. Soweit ist es allerdings nicht gekommen :wink:
Nach langem hin und her habe ich mich letztendlich doch dazu entschlossen, von den benötigten Standardklassen abzuleiten, und dort die jeweilige Funktionalität direkt einzubauen.

Nichts desto trotz war dieser Thread wiedermal eine Erfahrung und ich habe etwas dazu gelernt: Interfaces und Helferklassen - danke an alle, die mir in diesem Thread geantwortet haben :!:

Und nebenbei werde ich mich dann noch mal dem Thema 'Assoziation' widmen - danke hier an Jelly :wink:

Sidorion 9. Okt 2007 09:01

Re: Basisklasse und davon abgeleitet drei Standardklassen
 
Na da hört mal wieder keiner zu :zwinker: . Dein Problem löst sich wie folgt:
Delphi-Quellcode:
Type
  // Interface, das kriegen alle drei Klassen
  IMyInterface=interface(IInterface)
//hier kommt dann ne GUID, die wird automatisch erzeugt
   procedure MyWind;
  end;
  //Helperklasse für das Interface. Diese weiss, was zu tun ist, wenn die Methoden gerufen werden
  TMyIntfHelper=Class(TObject)
   FMemberusw: Typ;
  public
   procedure MyWnd;
  end;
  // ein Beispiel
  TMyEdit=Class(TEdit,IMyInterface)
   private
    FHelper: TMyIntfHelper;
   ...

   public
    property MyHelper: TMyIntfHelper Read FHelper implements IMyInterface;
  end;
  // mehr ist in TMyEdit im prinzip nicht zu schreiben, damit das Interface implementiert wird
TMyIntfHelper ist ein Delegat, der alle Methoden von IMyInterface implementiert. Dieser muss nun in jeder Klasse, die IMyInterface deklariert instanziert werden und erledigt dort die Drecksarbeit. Jetzt kannst Du problemlos das von TEdit geerbte TMyEdit als IMyInterface ansprechen und die Methoden benutzen. Das selbe würde dann für alle anderen Klassen mit dem Interface gelten.
Der Schlüssel liegt sozusagen in der Direktive Implements. Die sorgt dafür, dass die angegebene Property für die Bearbeitung des Interfaces sorgt. Die Klasse selber muss sich darum nichtmehr kümmern.
Dieses Konstrukt ist wesentlich eleganter, als Mehrfachvererbung, da hier das Diamantproblem garnicht entstehen kann, jedoch alle Möglichkeiten gegeben sind.
Nachtrag: Jetzt kannst Du einfach TMyEdit.MyWind rufen, alsob das Interface direkt in TMyEdit implementiert wäre.

s-off 9. Okt 2007 09:34

Re: Basisklasse und davon abgeleitet drei Standardklassen
 
Zitat:

Zitat von Sidorion
Na da hört mal wieder keiner zu :zwinker:

Nun - gehört schon, aber nicht verstanden :wink:
Wahrscheinlich war das auch genau die 'eine Property', die Hansa meinte.

Ich werde mir das Ganze mal verinnerlichen - vielen Dank :-D

Edit: Eine Frage habe ich dennoch:

Wie kann ich denn jetzt in TMyIntfHelper.MyWind auf Eigenschaften des späteren Edits zugreifen?
Ich habe also in TMyIntfHelper einige Felder. Diese muss ich der Methode MyWind den Eigenschaften des späteren Edits zuweisen, bspw so:

Delphi-Quellcode:
  TMyIntfHelper=Class(TObject)
   FEinString: String;
  public
   procedure MyWind;
  end;

 Procedure TMyIntfHelper.MyWind
 begin
   MeinSpäteresEdit.Text := FEinString;
 end;
MeinSpäteresEdit kennt er ja nicht. Gibt es da irgendwie eine Art Platzhalter?

Sidorion 9. Okt 2007 10:40

Re: Basisklasse und davon abgeleitet drei Standardklassen
 
Na du könntest beispielsweise den Helper von TControl ableiten. Dann wird in den Owner (THelper.Create(Self)) das Objekt geschrieben und du kannst dann im Helper über den Owner und RTTI (Unit Typinfo) zugreifen. Du kannst auch einen Event im Helper deklarieren, im Konstruktor Methodenzeiger übergeben usw.
Dir stehen hier sämtliche Objektkommunikationsmöglichkeiten offen.

Jelly 9. Okt 2007 12:37

Re: Basisklasse und davon abgeleitet drei Standardklassen
 
Zitat:

Zitat von Sidorion
Jetzt kannst Du einfach TMyEdit.MyWind rufen, alsob das Interface direkt in TMyEdit implementiert wäre.

Sollte das nicht myEdit.MyWind heissen. Oder greifst du tatsächlich direkt über die Klasse zu und nicht über die Instanz.

Das ist eine interessante Sache, mit dem "implements". Das kannte ich noch nicht. Werd mir das heut abend aber auch mal reinziehen.


Alle Zeitangaben in WEZ +1. Es ist jetzt 04:50 Uhr.
Seite 3 von 5     123 45      

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