![]() |
Re: Basisklasse und davon abgeleitet drei Standardklassen
Zitat:
Zitat:
:!: 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. |
Re: Basisklasse und davon abgeleitet drei Standardklassen
Delphi-Quellcode:
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..?
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; |
Re: Basisklasse und davon abgeleitet drei Standardklassen
Zitat:
|
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; |
Re: Basisklasse und davon abgeleitet drei Standardklassen
Hallo,
Zitat:
Gruß Hawkeye |
Re: Basisklasse und davon abgeleitet drei Standardklassen
Guten Morgen.
Zitat:
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: |
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:
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.
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 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. |
Re: Basisklasse und davon abgeleitet drei Standardklassen
Zitat:
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:
MeinSpäteresEdit kennt er ja nicht. Gibt es da irgendwie eine Art Platzhalter?
TMyIntfHelper=Class(TObject)
FEinString: String; public procedure MyWind; end; Procedure TMyIntfHelper.MyWind begin MeinSpäteresEdit.Text := FEinString; end; |
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. |
Re: Basisklasse und davon abgeleitet drei Standardklassen
Zitat:
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 18:16 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz