Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Methoden einer Kompo überschreiben ohne eigene abzuleiten (https://www.delphipraxis.net/52338-methoden-einer-kompo-ueberschreiben-ohne-eigene-abzuleiten.html)

Delphi-Freak 28. Aug 2005 11:13


Methoden einer Kompo überschreiben ohne eigene abzuleiten
 
Hi!

Hab mal wieder eine Frage. Wie kann ich die Methoden, Eigenschaften etc. eines Objekt überschreiben ohne dabei ein eigenes Objekt ableiten zu müssen.
Konkret habe ich mir SynEdit etwas abgeändert. Jetzt gibt es nur ein Problem, wenn eine neue Version herauskommt, oder so. Deshalb wäre es besser, diese Änderungen nicht direkt zu machen. Warum ich keine eigene Kompo ableiten will, liegt darin, dass es bei SynEdit ja nicht nur eine Kompo gibt (TSynEdit) sondern auch viele andere (wie z.B. TSynEditStringList). So müsste ich also die SynEdit Kompo ableiten und in der alle Unterobjekte überschreiben, die ich geändert habe, auf den neuen Namen.
Gibt es da also irgeneine Möglichkeit - würde mir einige Arbeit ersparen

LG, Gerhard

SirThornberry 28. Aug 2005 11:29

Re: Methoden einer Kompo überschreiben ohne eigene abzuleite
 
du könntest das original TSynEdit umbenennen (TBaseSynEdit) die unit auch umbennen und dann deine abgleitete Klasse "TSynEdit" nennen und die Unit davon so nennen wie die des originalen SynEdits hieß. Somit leiten dann alle von deinem SynEdit ab.

Delphi-Freak 28. Aug 2005 11:59

Re: Methoden einer Kompo überschreiben ohne eigene abzuleite
 
Danke mal, jedoch heißt das, dass ich bei jeder neuen Version die ganzen Komponenten-Namen abändern müsste, und es dann immer noch nur für dieses eine Projekt verwendbar wäre; und alle Kompos die ich nicht abändere müsste ich den Namen bei "Verweisen" auch abändern. Irgenwie ist es da glaube ich noch einfacher, meine Kompo TMySynEdit oder so zu nennen und dann die "Nebenkompos" TMySynEditStringList usw. und in TMySynEdit auch auf diese referenzieren.
Es geht mir also nicht um den Namen, den ich im Form verwende, sondern darum, die SynEdit-Pas-Dateien nicht abzuändern und trotzdem möglichst wenig Code mir meinen Änderungen zu haben, was bei einem Ableiten nicht unbedingt der Fall wäre.

LG

Edit: Da kommt mir jetzt eine andere Idee. Wenn ich die geänderten Dateien in das Verzeichnis meines Projekts gebe, verwendet er dann diese Dateien oder die originalen die irgenwo unter C:\Programme\Borland\Delphi2005\... liegen?

Edit2: Alles muss gelernt sein - auch BBCode :zwinker:

SirThornberry 28. Aug 2005 12:31

Re: Methoden einer Kompo überschreiben ohne eigene abzuleite
 
bevorzugt werden die dateien die dem Projekt hinzugefügt sind.

Warum musst du dann immer mehrere Dateien umbennen, du musst doch nur die eine datei (dort wo TSynEdit drin ist) umbenennen.

Robert_G 28. Aug 2005 12:35

Re: Methoden einer Kompo überschreiben ohne eigene abzuleite
 
Warum streubst du sich so davor, eine eigene Ableitung zu nehmen?
Kann ich wirklich nicht nachvollziehen...
So hättest du auch eine gewisse Abstraktion, die dich vor Änderungen im Interface von Synedit - Klassen schützt...

Delphi-Freak 28. Aug 2005 14:23

Re: Methoden einer Kompo überschreiben ohne eigene abzuleite
 
Zitat:

Zitat von SirThornberry
bevorzugt werden die dateien die dem Projekt hinzugefügt sind.

Was heißt "dem Projekt hinzugefügt", meinst du den Ordner angegeben (irgendwo in den Optionen oder so)? :gruebel:

Zitat:

Zitat von SirThornberry
Warum musst du dann immer mehrere Dateien umbennen, du musst doch nur die eine datei (dort wo TSynEdit drin ist) umbenennen.

Weil ich auch Änderungen in z.B. TSynEditStringList machen möchte...


Zitat:

Zitat von Robert_G
Warum streubst du sich so davor, eine eigene Ableitung zu nehmen?
Kann ich wirklich nicht nachvollziehen...
So hättest du auch eine gewisse Abstraktion, die dich vor Änderungen im Interface von Synedit - Klassen schützt...

Naja, ich möchte es in folgendem Beispiel demonstrieren:
Nehmen wir an TSynEdit.Lines wäre vom Typ TSynEditStringList (auch wenn es nicht ganz so ist).
Nun möchte ich in TSynEditStringList eine weitere Funktion haben.
Kann ich nun die Kompos direkt "überschreiben", so füge ich TSynEditStringList die eine Funktion hinzu und bin fertig. Beim Ableiten muss ich eine Klasse TMySynEdit definieren, in der ich die Property Lines auf TMySynEditStringList überschreibe und zusätzlich brauche ich noch die Klasse TMySynEditStringList, die ich dann um die eine Funktion erweitere. Eigentlich müsste ich dann noch alle anderen Kompos überschreiben, die irgendwie die Klasse TSynEditStringList (bzw. TSynEdit) verwenden um ihnen zu sagen, dass sie TMySynEditStringList verwenden sollen.
Das war eigentlich der Grund - hoffe ich habe mich klar ausgedrückt.


LG, Delphi-Freak

Delphi-Freak 28. Aug 2005 14:32

Re: Methoden einer Kompo überschreiben ohne eigene abzuleite
 
Hey genial. Bin grad durch rumtesten draufgekommen:
Delphi-Quellcode:
TButton2 = class(TButton);
TButton = class(TButton2)
published
   procedure alert;
end;
und schon ist TButton eine Methode hinzugefügt. Habe es ausgetestet mit einer Form, darauf im OI Designer einen TButton draufplatziert und dann bei on Click Button1.alert aufgerufen und es hat funktioniert :spin2: :spin2:
Zwar nicht sehr elegant und irgendwie etwas komisch, aber es funktioniert!!!

Edit: Einrückung augebessert
Edit2: OI ist etwas falsch

jbg 28. Aug 2005 14:38

Re: Methoden einer Kompo überschreiben ohne eigene abzuleite
 
Zitat:

Zitat von Delphi-Freak
Zwar nicht sehr elegant und irgendwie etwas komisch, aber es funktioniert!!!

Was ist daran komisch? Das ist nichts anderes als eine Ableitung. Nur das du die Basisklasse zu Gunsten der neuen Klassen umbenannt hast.

Delphi-Freak 28. Aug 2005 14:46

Re: Methoden einer Kompo überschreiben ohne eigene abzuleite
 
Wie habe ich die Basisklasse umbenannt, eigentlich habe ich sie ja nur durch Neudefinition überschrieben, oder :gruebel:

Flocke 28. Aug 2005 15:17

Re: Methoden einer Kompo überschreiben ohne eigene abzuleite
 
Das hättest du auch kürzer so haben können:
Delphi-Quellcode:
TButton = class(StdCtrls.TButton)
published
   procedure alert;
end;
Sicher ist das jetzt eine neue Klasse, genaugenommen die Klasse "DeineUnit.TButton" und nicht "StdCtrls.TButton". Wenn eine andere Unit dieses "TButton" benutzt, dann hängt von der Reihenfolge in der uses-Klausel ab, welcher TButton erzeugt wird.

Wenn du jetzt auf diese Weise "TSynEditStrList" neu definierst, dann sieht TSynEdit davon ja nichts, weil TSynEdit deine Unit nicht benutzt.

Delphi-Freak 28. Aug 2005 15:52

Re: Methoden einer Kompo überschreiben ohne eigene abzuleite
 
Das ist aber schade... :cry:
Trotzdem danke, sonst hätte ich gesucht und gesucht und wäre nicht draufgekommen :(

Edit: Oja, noch eine Frage:
Zitat:

Zitat von Flocke
Wenn eine andere Unit dieses "TButton" benutzt, dann hängt von der Reihenfolge in der uses-Klausel ab, welcher TButton erzeugt wird.

Welche Unit ist dann höherrangig bzw. wird benutzt. Die früher oder die später definierte?

SirThornberry 28. Aug 2005 16:18

Re: Methoden einer Kompo überschreiben ohne eigene abzuleite
 
die später definierte (probieren hilf). Das sieht man unter anderem wenn man mit TBitmap arbeitet. TBitmap ist in der unit Windows und in der Unit Graphics definiert. Wenn du mal die unit Windows in den Uses nach der Unit Graphics aufführst wirst du sehen das rumgemeckert wird das es kein Object ist oder so weil die TBitmap-Definition in der Windows-Unit keine Klasse ist.

Hansa 28. Aug 2005 16:19

Re: Methoden einer Kompo überschreiben ohne eigene abzuleite
 
Zitat:

Zitat von Delphi-Freak
Wie habe ich die Basisklasse umbenannt, eigentlich habe ich sie ja nur durch Neudefinition überschrieben, oder :gruebel:

Was Du gemacht hast ? Ungefähr das, was Robert_G vorgeschlagen hat. :mrgreen: Von einer vorhandenen Basisklasse abgeleitet.

Edit : Ahhhh, noch was übersehen. Was ist denn das ? :shock:
Zitat:

Zitat von Flocke
Delphi-Quellcode:
TButton = class(StdCtrls.TButton)
published
   procedure alert;
end;

Geht das so überhaupt ? Hier sieht man manchmal wirklich unglaubliche Codefetzen. :lol: Wenn schon dann aber so:

Delphi-Quellcode:
TMeinButton = class(TButton)
published
   procedure alert;
end;
Edit2 :

Zitat:

Welche Unit ist dann höherrangig bzw. wird benutzt. Die früher oder die später definierte?
Da fängts schon an. In einem Programm 2 unterschiedliche TButton. Geht irgendwann mit Sicherheit schief.

tommie-lie 28. Aug 2005 16:37

Re: Methoden einer Kompo überschreiben ohne eigene abzuleite
 
Zitat:

Zitat von Hansa
Edit : Ahhhh, noch was übersehen. Was ist denn das ? :shock:
Zitat:

Zitat von Flocke
Delphi-Quellcode:
TButton = class(StdCtrls.TButton)
// ...

Geht das so überhaupt ?

Sowas nennt sich Fully Qualified Name und ist durchaus legitim, soland eine solche Definition nicht unten an den Interface-Abschnitt der Unit StdCtrls angehangen wird. Mach dich nicht über Dinge lustig, die du nicht begreifst.

Edit: Wenn ich einen schließenden bbCode entferne kann das ja nicht gut aussehen...

Delphi-Freak 28. Aug 2005 16:57

Re: Methoden einer Kompo überschreiben ohne eigene abzuleite
 
Wie ist das also nochmal. Wenn ich TButton als Klasse von StdCtrls.TButton ableite, dann ist das nur in der aktuellen Unit gültig (bzw. in Units die diese Unit einbinden und TButton nicht überschreiben), oder? :gruebel:

Khabarakh 28. Aug 2005 17:05

Re: Methoden einer Kompo überschreiben ohne eigene abzuleite
 
Wenn du nur Methoden hinzufügen willst, könntest du doch (dank D2005) Delphi-Referenz durchsuchenclass helpers benutzen. Du kannst auch Methoden der Klasse verdecken, wie du diese dann aber im Helper wieder aufrufen kannst, kann ich dir nicht sagen (mit inherited hat sich Delphi aufgehängt :stupid: ).

tommie-lie 28. Aug 2005 17:06

Re: Methoden einer Kompo überschreiben ohne eigene abzuleite
 
Zitat:

Zitat von Delphi-Freak
Wenn ich TButton als Klasse von StdCtrls.TButton ableite, dann ist das nur in der aktuellen Unit gültig (bzw. in Units die diese Unit einbinden und TButton nicht überschreiben), oder? :gruebel:

Jupp, so isset.
Wenn dann eine Unit sowohl ExtCtrls, als auch deine Unit einbindet, gibt es einen Namenskonflikt, da ja TButton einmal in ExtCtrls und einmal in deiner Unit. Welche dann bevorzugt wird, kann ich nicht sagen, in so eine unangenehme Situation bin ich noch nicht gekommen, deswegen ist es dann auch besser, den Fully Qualified Name der Klasse zu benutzen, also entweder ExtCtrls.TButton, wenn ich einen Normalo-Button haben will, oder MeineUnit.TButton, wenn ich meinen Enhanced-Button haben will.

Delphi-Freak 28. Aug 2005 17:59

Re: Methoden einer Kompo überschreiben ohne eigene abzuleite
 
Vielen, vielen Dank einmal!
Ihr seid eine große Hilfe! :thumb:
Das mit class helpers muss ich mir noch anschauen, klingt aber viel versprechend.

LG, Gerhard

Edit:ad »class helpers«: irgendwie werde ich da aus der Hilfe nicht gescheit. Hat das irgendwas mit »IClassFactory« zu tun, bzw. wie kann ich das implementieren? :roll:

tommie-lie 28. Aug 2005 18:25

Re: Methoden einer Kompo überschreiben ohne eigene abzuleite
 
Ich habe keine Delphi2005-Hilfe, aber nach dem, was hier geschrieben steht, sieht das alles ziemlich straightforward aus, ohne Interfaces.

Robert_G 28. Aug 2005 19:02

Re: Methoden einer Kompo überschreiben ohne eigene abzuleite
 
Zitat:

Zitat von tommie-lie
Ich habe keine Delphi2005-Hilfe, aber nach dem, was hier geschrieben steht, sieht das alles ziemlich straightforward aus, ohne Interfaces.

Ich weiß nicht wie es in Win32 gelöst wird. Die .Net Variante ist eher als krank zu bezeichnen. Zumindest wenn man seine "Vorteile" zu Herzen nehmen würde. :wall: Dann könnte jeder mit einem "sauberen" .Net compiler einpacken... :shock:

@delphiFreak
Ich verstehe immer noch nicht wo das Problem liegt...
Warum musst du für all die anderen Klassen auch Ableitungen erstellen?
Ich sehe in deinem Bleistift nur die eigentliche neue Klasse und das SynEdit, dass sie verwenden würde.
Dein SynEdit ist wäre aber weiter voll kompatibel zum Rest.
Wo ist das Problem dabei? Du machst dich doch total inkompatibel zu allem anderen wenn du in den Sourcen rumwurschtelst.
Ist das überhaupt erlaubt, ohne die Änderungen wieder als OSS zu veröffentlichen?
Und was hält man dann wohl von deinem Programm, wenn man dann sieht, dass du nicht die Lust hattest, es sauber zu lösen? :gruebel:

Delphi-Freak 28. Aug 2005 20:58

Re: Methoden einer Kompo überschreiben ohne eigene abzuleite
 
Naja, das stimmt. Das mit dem Hergeben ist so eine Sache, deshalb habe ich mich mal fast entschlossen mein Proggy nicht herzugeben, zumindest einstweilen :mrgreen:
Ich habe zwar in den Sourcen rumgewurschtelt, jetzt aber erkannt, dass das nicht die saubere Lösung ist und deshalb möchte ich die Änderungen in mein eigenes Projekt einbauen.
Nun nochmal zur Erklärung des "Problems", am Beispiel irgend eines anderen Objekts, z.B. TMainKompo. Die ganzen Units usw. von TMainKompo haben noch andere Komponenten dabei, z.B. TSubKompo1 und TSubKompo2.
TMainKompo.Prop1 ist vom Typ TSubKompo1, TMainKompo.Prop2 vom Typ TSubKompo2. Ich lade also diesen ganzen Source irgendwo runter und möchte jetzt zu TMainKompo noch eine Eigenschaft Prop3 hinzufügen, zu TSubKompo1 noch Prop11 und zu TSubKompo2 noch Prop21.
Jetzt würde ich gerne kurz schreiben, z.B.:
Delphi-Quellcode:
type
   TKompo = class(TKompo)
      property Prop3: Integer;
   end;

   TSubKompo1 = class(TSubKompo1)
      property Prop11: Integer;
   end;

   TSubKompo2 = class(TSubKompo2)
      property Prop21: Integer;
   end;
Nur geht es eben nicht ganz so. Wenn ich meine eigenen Kompos ableite müsste ich nun noch etwas hinzufügen:
Code:
type
   TMyKompo = class(TKompo)
[color=#ff0000]     property Prop1: TMySubKompo1;
      property Prop2: TMySubKompo2;[/color]
      property Prop3: Integer;
   end;

   TMySubKompo1 = class(TSubKompo1)
      property Prop11: Integer;
   end;

   TMySubKompo2 = class(TSubKompo2)
      property Prop21: Integer;
   end;
In diesem Fall wären es nur 2 Zeilen, in anderen Fällen könnten es aber auch mehr sein...
Zum Schluss noch zur Verdeutlichung, den Code den ich mir irgenwo runtergeladen habe:
Delphi-Quellcode:
type
   TKompo = class(TObject)
      property Prop1: TMySubKompo1;
      property Prop2: TMySubKompo2;
      property Haha1: String;
   end;

   TSubKompo1 = class(TObject)
      property Haha11: String;
   end;

   TSubKompo2 = class(TObject)
      property Haha21: String;
   end;
Klarer Weise sind das alles nur Beispiele, die Sinnhaftigkeit der Kompos ist also anzuzweifeln :mrgreen:

Ich hoffe, jetzt habe ich mich verständlich ausgedrückt, sonst bitte nochmal rückfragen!!

LG & gute Nacht dann... , ich


Edit: Achja, @tommie-lie: deinen Beitrag habe ich nicht übersehen, ich schau mir dann den Link morgen oder so an!


Edit2: Tippfehler ausgebessert

tommie-lie 28. Aug 2005 21:06

Re: Methoden einer Kompo überschreiben ohne eigene abzuleite
 
Zitat:

Zitat von Robert_G
Ist das überhaupt erlaubt, ohne die Änderungen wieder als OSS zu veröffentlichen?

Mit den Class Helpers wäre es auf jeden Fall erlaubt, denn man hat keine Modifikationen am Code vorgenommen.
Allerdings ist jede Anwendung ein von SynEdit abgeleitetes Werk. Meine Spezialität ist die GPL, für die LGPL und die MPL, die von SynEdit laut Projektseite verwendet werden, müsste ich nachschauen, und dafür bin ich jetzt zu faul ;-) Wäre es GPL, müsste jede Anwendung, die SynEdit benutzt, ebenfalls unter GPL sein.

Delphi-Freak 29. Aug 2005 09:09

Re: Methoden einer Kompo überschreiben ohne eigene abzuleite
 
So, das mit den Class Helpers: Sagen wir so, es funktoiniert halb.
Delphi-Quellcode:
   TTest = class
      public
         SomeStr: String;
   end;

   TTestHelper = class helper for TTest
      public
         procedure SomeInt;
   end;
Das funktioniert ohne Probleme und ich kann auch in TTest auf SomeInt zugreifen (und in SomeInt auf SomeStr).

Was aber nicht funktioniert, ist eine Variable zu definieren:
Delphi-Quellcode:
   TTest = class
      public
         SomeStr: String;
   end;

   TTestHelper = class helper for TTest
      public
         test: String;
         procedure SomeInt;
   end;
Da sagt das Delphi dann »Felddefinition nicht erlaubt nach Methoden oder Eigenschaften«

Wenn ich Properties definieren will, dann kommen auch Probleme:
  • Beim Zugriff auf SomeStr: »Feld- oder Methodenbezeichner erwartet«
  • Zugriff auf eine in TTestHelper definierte Variable ist aus dem Grund schon nicht möglich, weil ich ja gar keine Variablen definieren kann...
Zusätzlich beschwert sich das Delphi beim Zugriff auf diese Property mit »Einer Nur-Lesen Eigenschaft kann kein Wert zugewiesen werden«.

Also irgendwie funktionierts eben nicht ganz :gruebel:

LG


Alle Zeitangaben in WEZ +1. Es ist jetzt 12:32 Uhr.

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