Autor |
Beitrag |
OlafSt
      
Beiträge: 486
Erhaltene Danke: 99
Win7, Win81, Win10
Tokyo, VS2017
|
Verfasst: Do 10.03.11 12:43
Hallo Freunde,
ich sehe den Wald vor Bäumen nicht mehr, fürchte ich  Naja, nach all den Jahren (begonnen mit Turbo Pascal 6.0 in OOP zu denken) kann sowas mal vorkommen. Mein Problem ist, das man offensichtlich Members gleichen Namens nicht korrekt ansprechen kann. Folgender Code (Delphi 7) mag verdeutlichen, was ich meine:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19:
| TUsedClass1 = class(TObject) private FInternalValue: string; function GetInternalValue: string; protected public constructor Create; property InternalValue: string read GetInternalValue; end;
TUsedClass2 = class(TObject) private FInternalValue: string; function GetInternalValue: string; protected public constructor Create; property InternalValue: string read GetInternalValue; end; |
Zwei simple Klassen, die sich nur im Konstruktor unterscheiden:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19:
| constructor TUsedClass1.Create; begin self.FInternalValue:='Hallo 1'; end;
function TUsedClass1.GetInternalValue: string; begin result:=self.FInternalValue; end;
constructor TUsedClass2.Create; begin self.FInternalValue:='Hallo 2'; end;
function TUsedClass2.GetInternalValue: string; begin Result:=self.FInternalValue; end; |
So. Nun basteln wir uns ne Klasse, die TUsedClass1 als Member beinhaltet:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16:
| TAnyClass1 = class(TObject) public Fx: TUsedClass1; constructor Create; function GetFxValue: string; virtual; end;
constructor TAnyClass1.Create; begin self.Fx:=TUsedClass1.Create; end;
function TAnyClass1.GetFxValue: string; begin Result:=self.Fx.InternalValue; end; |
Von dieser Klasse leiten wir eine weitere Klasse ab. Das besondere ist das Feld "Fx", das nun nicht mehr vom Typ TUsedClass1 ist, sondern vom Typ TUsedClass2:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16:
| TAnyClass2 = class(TAnyClass1) public Fx: TUsedClass2; constructor Create; function GetFxValue: string; override; end;
constructor TAnyClass2.Create; begin self.Fx:=TUsedClass2.Create; end;
function TAnyClass2.GetFxValue: string; begin Result:=inherited GetFxValue; end; |
So weit, so simpel. Instanziere ich nun ein TAnyClass2 und rufe GetFxValue auf, wird korrekt in TAnyClass2.GetFxValue gesprungen, dann zu TAnyClass1.GetFxValue. Alles logisch. Der Zugriff in GetFxValue erfolgt aber auf ein Feld "Fx" vom Typ TUsedClass1 - das nicht existiert und folglich eine Exception geworfen wird.
Ich habe so ziemlich alles probiert, was mir eingefallen ist, und die einzige Lösung ist, kurzerhand den Code von TAnyClass1.GetFxValue 1:1 zu duplizieren. Aber dann brauche ich keine Verebung mehr.
Wie dicht ist der Wald, in dem ich stehe ? Oder ist das, was ich da vorhabe, gar nicht vorgesehen ?
Danke fürs helfen,
Olaf
_________________ Lies, was da steht. Denk dann drüber nach. Dann erst fragen.
|
|
bummi
      
Beiträge: 1248
Erhaltene Danke: 187
XP - Server 2008R2
D2 - Delphi XE
|
Verfasst: Do 10.03.11 13:23
hier fehlte inherited
Delphi-Quelltext 1: 2: 3: 4: 5:
| constructor TAnyClass2.Create; begin inherited; self.Fx:=TUsedClass2.Create; end; |
das was Du vermutlich vorhast wäre über eine gemeinsame Basisklasse für für TUsedClass1/TUsedClass2 mit einem virtuellen GetInternalValue zu lösen.
_________________ Das Problem liegt üblicherweise zwischen den Ohren H₂♂
DRY DRY KISS
|
|
OlafSt 
      
Beiträge: 486
Erhaltene Danke: 99
Win7, Win81, Win10
Tokyo, VS2017
|
Verfasst: Do 10.03.11 13:34
bummi hat folgendes geschrieben : |
das was Du vermutlich vorhast wäre über eine gemeinsame Basisklasse für für TUsedClass1/TUsedClass2 mit einem virtuellen GetInternalValue zu lösen. |
Ups, das mit dem inherited ist logisch. Daher auch der Absturz.
Das mit der gemeinsamen Basisklasse für TUsedClass habe ich schon versucht. Ohne das fehlende Inherited krachts, mit dem Inherited bekomme ich 2x ein ShowMessage mit "Hallo 1". Es wird also weiterhin auf das Fx mit dem Typ TUsedClass1 zugegriffen.
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22:
| TUsedClass = Class(TObject) private FInternalValue: string; function GetInternalValue: string; virtual; protected public property InternalValue: string read GetInternalValue; end;
TUsedClass1 = class(TUsedClass) private protected public constructor Create; end;
TUsedClass2 = class(TUsedClass) private protected public constructor Create; end; |
Natürlich kann ich GetInternalValue jedesmal überschreiben - aber dann habe ich ja 3x denselben Code und genau das soll die Vererbung ja vermeiden. Ich habe auch schon das property weggenommen und den Getter in den public-Bereich verschoben. Same Result.
_________________ Lies, was da steht. Denk dann drüber nach. Dann erst fragen.
|
|
bummi
      
Beiträge: 1248
Erhaltene Danke: 187
XP - Server 2008R2
D2 - Delphi XE
|
Verfasst: Do 10.03.11 14:05
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139:
| unit Unit1;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls;
type TUsedClassBase = class(TObject) private FInternalValue: string; function GetInternalValue: string;virtual; protected public constructor Create; property InternalValue: string read GetInternalValue; end;
TUsedClass1 = class(TUsedClassBase) private FInternalValue: string; function GetInternalValue: string;override; protected public constructor Create; property InternalValue: string read GetInternalValue; end;
TUsedClass2 = class(TUsedClassBase) private FInternalValue: string; function GetInternalValue: string;override; protected public constructor Create; property InternalValue: string read GetInternalValue; end; TAnyClass1 = class(TObject) public Fx: TUsedClass1; constructor Create; function GetFxValue: string; virtual; end;
TAnyClass2 = class(TAnyClass1) public Fx: TUsedClass2; constructor Create; function GetFxValue: string; override; end;
TForm1 = class(TForm) Button1: TButton; procedure Button1Click(Sender: TObject); private public end;
var Form1: TForm1;
implementation
{$R *.dfm} constructor TUsedClass1.Create; begin self.FInternalValue:='Hallo 1'; end;
function TUsedClass1.GetInternalValue: string; begin result:=self.FInternalValue; end;
constructor TUsedClass2.Create; begin self.FInternalValue:='Hallo 2'; end;
function TUsedClass2.GetInternalValue: string; begin Result:=self.FInternalValue; end;
constructor TAnyClass1.Create; begin self.Fx:=TUsedClass1.Create; end;
function TAnyClass1.GetFxValue: string; begin Result:=FX.GetInternalValue; end;
constructor TAnyClass2.Create; begin inherited; self.Fx:=TUsedClass2.Create; end;
function TAnyClass2.GetFxValue: string; begin Result:= FX.GetInternalValue; end; procedure TForm1.Button1Click(Sender: TObject); begin With TAnyClass1.Create do begin Showmessage('TAnyClass1 ' + GetFxValue); Free; end; With TAnyClass2.Create do begin Showmessage('TAnyClass2 ' + GetFxValue); Free; end; end;
constructor TUsedClassBase.Create; begin inherited; end;
function TUsedClassBase.GetInternalValue: string; begin Result := ''; end;
end. |
_________________ Das Problem liegt üblicherweise zwischen den Ohren H₂♂
DRY DRY KISS
|
|
OlafSt 
      
Beiträge: 486
Erhaltene Danke: 99
Win7, Win81, Win10
Tokyo, VS2017
|
Verfasst: Do 10.03.11 14:17
Hui, danke !
Allerdings: TUsedClass1.GetInternalValue wird in TUsedClass2 1:1 dupliziert. Desgleichen in TAnyClass1.GetFxValue und TAnyClass2.GetFxValue, die 1:1 dupliziert sind.
Wenn wir uns von meinem Beispiel lösen und in mein real existierendes Problem springen, muß ich nun 15 Routinen mit ein paar hundert Zeilen Code 1:1 duplizieren, denn sie machen beides identisch, nur auf einer anderen Membervariablen. Ist also pures Copy & Paste.
Ist das wirklich so beabsichtigt ? Ehrlich gesagt sehe ich plötzlich nicht mehr den Sinn hinter der Vererbung - außer das ich immer denselben Prozedurnamen habe. Das kanns doch nicht sein 
_________________ Lies, was da steht. Denk dann drüber nach. Dann erst fragen.
|
|
bummi
      
Beiträge: 1248
Erhaltene Danke: 187
XP - Server 2008R2
D2 - Delphi XE
|
Verfasst: Do 10.03.11 14:39
brauchst Du ja nicht, ich hatte neben dem Arbeiten schnell was in Deinen Code reingeflickt, so wie unten geht es auch, gegf. kannst Du noch mehr optimieren, bin gerade etwas im Stress...
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128:
| unit Unit1;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls;
type TUsedClassBase = class(TObject) private FInternalValue: string; function GetInternalValue: string;virtual; protected public constructor Create; property InternalValue: string read GetInternalValue; end;
TUsedClass1 = class(TUsedClassBase) private FInternalValue: string; protected public constructor Create; end;
TUsedClass2 = class(TUsedClassBase) private FInternalValue: string; protected public constructor Create; end;
TAnyClass1 = class(TObject) public Fx: TUsedClass1; constructor Create; function GetFxValue: string; virtual; end;
TAnyClass2 = class(TAnyClass1) public Fx: TUsedClass2; constructor Create; function GetFxValue: string; override; end;
TForm1 = class(TForm) Button1: TButton; procedure Button1Click(Sender: TObject); private public end;
var Form1: TForm1;
implementation
{$R *.dfm} constructor TUsedClass1.Create; begin FInternalValue:='Hallo 1'; end;
constructor TUsedClass2.Create; begin FInternalValue:='Hallo 2'; end;
constructor TAnyClass1.Create; begin Fx:=TUsedClass1.Create; end;
function TAnyClass1.GetFxValue: string; begin Result:=FX.GetInternalValue; end;
constructor TAnyClass2.Create; begin inherited; Fx:=TUsedClass2.Create; end;
function TAnyClass2.GetFxValue: string; begin Result:= FX.GetInternalValue; end; procedure TForm1.Button1Click(Sender: TObject); begin With TAnyClass1.Create do begin Showmessage('TAnyClass1 ' + GetFxValue); Free; end; With TAnyClass2.Create do begin Showmessage('TAnyClass2 ' + GetFxValue); Free; end; end;
constructor TUsedClassBase.Create; begin inherited; end;
function TUsedClassBase.GetInternalValue: string; begin Result := ''; end;
end. |
_________________ Das Problem liegt üblicherweise zwischen den Ohren H₂♂
DRY DRY KISS
|
|
OlafSt 
      
Beiträge: 486
Erhaltene Danke: 99
Win7, Win81, Win10
Tokyo, VS2017
|
Verfasst: Do 10.03.11 15:13
Okay, das habe ich mal probiert. Beide Aufrufe
Delphi-Quelltext 1:
| Showmessage('TAnyClass1 ' + GetFxValue); |
landen bei TUsedBaseClass.GetInternalValue. Ergo ist die Ausgabe "TAnyClass1 " und "TAnyClass2 " in den ShowMessages. Erstaunlicherweise zeigt der Debugger, sobald man in den Routinen "GetFxValue" die Maus auf "FX." hovern läßt, korrekt den Inhalt von FInternalValue an.
_________________ Lies, was da steht. Denk dann drüber nach. Dann erst fragen.
|
|
bummi
      
Beiträge: 1248
Erhaltene Danke: 187
XP - Server 2008R2
D2 - Delphi XE
|
Verfasst: Do 10.03.11 18:18
ich hatte ja geschrieben daß ich gerade im Druck bin....
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118:
| unit Unit1;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls;
type TUsedClassBase = class(TObject) private FInternalValue: string; protected public constructor Create; property InternalValue: string read FInternalValue; end;
TUsedClass1 = class(TUsedClassBase) protected public constructor Create; end; TUsedClass2 = class(TUsedClassBase) protected public constructor Create; end;
TAnyClass1 = class(TObject) public Fx: TUsedClass1; constructor Create; function GetFxValue: string; virtual; end;
TAnyClass2 = class(TAnyClass1) public Fx: TUsedClass2; constructor Create; function GetFxValue: string; override; end;
TForm1 = class(TForm) Button1: TButton; procedure Button1Click(Sender: TObject); private public end;
var Form1: TForm1;
implementation
{$R *.dfm} constructor TUsedClass1.Create; begin FInternalValue:='Hallo 1'; end;
constructor TUsedClass2.Create; begin FInternalValue:='Hallo 2'; end;
constructor TAnyClass1.Create; begin Fx:=TUsedClass1.Create; end;
function TAnyClass1.GetFxValue: string; begin Result:=FX.InternalValue; end;
constructor TAnyClass2.Create; begin inherited; Fx:=TUsedClass2.Create; end;
function TAnyClass2.GetFxValue: string; begin Result:= FX.InternalValue; end; procedure TForm1.Button1Click(Sender: TObject); begin With TAnyClass1.Create do begin Showmessage('TAnyClass1 ' + GetFxValue); Free; end; With TAnyClass2.Create do begin Showmessage('TAnyClass2 ' + GetFxValue); Free; end; end;
constructor TUsedClassBase.Create; begin inherited; end;
end. |
_________________ Das Problem liegt üblicherweise zwischen den Ohren H₂♂
DRY DRY KISS
|
|
OlafSt 
      
Beiträge: 486
Erhaltene Danke: 99
Win7, Win81, Win10
Tokyo, VS2017
|
Verfasst: Do 10.03.11 19:18
Gut, das ganze funktioniert - entspricht aber auch genau dem, was ich hier als "merkwürdig" angesprochen habe.
Nehmen wir also an, in TUsedClass1 finden wir jede Menge Programmcode und Hilfsroutinen, um mit einer ISDN-Karte Daten zu übertragen und auch ein Telefongespräch zu führen.
Nehmen wir weiter an, in TAnyClass1 finden wir jetzt ein Member namens "isdn", vom Typ TUsedClass1. Und eine Methode, die so aussieht (ich poste das Monster mit Absicht, damit deutlich wird, was das Problem ist):
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73:
| procedure TAnyClass1.ActivateOutput(const Output: integer; const IsDuplex: boolean); begin if IsDuplex then frmMain.log.WriteToLog('>> Activate Outputs for Duplex',nil,1) else frmMain.log.WriteToLog('>> Activate Outputs for Simplex',nil,1); case Output of 0: begin frmMain.log.WriteToLog('>> Activate Output CC',nil,1); isdn.SendOutput(1-1,self.CC_Sound,self.CC_SubChannel-1); FCCUsed:=true; end; 1: begin if (FMon1ChannelUsed) and (FMon2ChannelUsed) then begin frmMain.log.WriteToLog('>> Activate Output MON1: No channel available',nil,1); exit; end; if IsDuplex then begin if (FMon2ChannelUsed) or (FMon1ChannelUsed) then begin frmMain.log.WriteToLog('>> Activate Output MON1 (Duplex): Not enough channels available',nil,1); exit; end;
frmMain.log.WriteToLog('>> Activate Output MON1',nil,1); isdn.SendOutput(5-1,self.Mon1_Sound,self.Mon1_SubChannel-1); frmMain.log.WriteToLog('>> Activate Output MON2',nil,1); isdn.SendOutput(6-1,self.Mon2_Sound,self.Mon2_SubChannel-1); FMon1ChannelUsed:=true; FMon2ChannelUsed:=true; FIsDuplex:=true; end else begin if not FMon1Channelused then begin frmMain.log.WriteToLog('>> Activate Output MON1',nil,1); isdn.SendOutput(5-1,self.Mon1_Sound,self.Mon1_SubChannel-1); FMon1ChannelUsed:=true; FIsDuplex:=false; end; end; end; 2: begin if (FMon1ChannelUsed) and (FMon2ChannelUsed) then begin frmMain.log.WriteToLog('>> Activate Output MON2: Not enough channels available',nil,1); exit; end; if ((FMon1ChannelUsed) or (FMon2ChannelUsed)) and (IsDuplex) then begin frmMain.log.WriteToLog('>> Activate Output MON2 (Duplex): Not enough channels available',nil,1); exit; end;
if IsDuplex then begin frmMain.log.WriteToLog('>> Activate Output MON1',nil,1); isdn.SendOutput(5-1,self.Mon2_Sound,self.Mon2_SubChannel-1); FMon1ChannelUsed:=true; FIsDuplex:=true; end else FIsDuplex:=false; frmMain.log.WriteToLog('>> Activate Output MON2',nil,1); isdn.SendOutput(6-1,self.Mon2_Sound,self.Mon2_SubChannel-1); FMon2ChannelUsed:=true; end; end; end; |
Bitte nicht über den Code aufregen, er stammt nicht von mir.
Nun habe ich TUsedClass2 erstellt, das sich nach außen hin exakt so verhält, wie TUsedClass1, nur das ich nicht via ISDN kommuniziere, sondern via UDP. Ergo habe ich auch eine neue AnyClass gebaut, nämlich TAnyClass2. Natürlich enthält TAnyClass2 auch wieder ein Member namens "isdn", aber diesmal vom Typ TUsedClass2.
Um die OOP voll zu nutzen, habe ich nun eine Instanz namens TAC, vom Typ TAnyClass1. Je nachdem, ob ich via ISDN oder UDP telefonieren will, ändere ich meine Instanzierung ab:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7:
| var TAC: TAnyClass1;
if UseISDN then TAC:=TAnyClass1.Create else TAC:=TAnyClass2.Create; |
Ist UseISDN=false, will ich also UDP nutzen, TAC ist also nun eine Instanz von TAnyClass2. Bei dem Versuch, TAC.ActivateOutput aufzurufen, lande ich aber unweigerlich in TAnyClass 1.ActivateOutput. Dort wird das Member "isdn" angesprochen, das aber gar nicht existiert (und auch nicht darf, schließlich gibts kein ISDN).
Die einzige LÖsung scheint zu sein, TAnyClass1.ActivateOutput zu kopieren (sie also virtuell zu machen und in TAnyClass2 per override zu überschreiben). Daraus folgt: Die oben angegebene Methode habe ich nun zweimal als exakte Kopie im Programmcode. Und das nur, damit das richtige Member namens "isdn" angesprochen wird.
Ist es in OOP nicht so, das man eben solche Duplikate durch Vererbung vermeiden können soll ? Und wenn das so ist: Was mache ich dann falsch ? Das ist der Wald, den ich im Moment nicht sehe...
_________________ Lies, was da steht. Denk dann drüber nach. Dann erst fragen.
|
|
bummi
      
Beiträge: 1248
Erhaltene Danke: 187
XP - Server 2008R2
D2 - Delphi XE
|
Verfasst: Do 10.03.11 23:36
vielleicht habe ich einen Hänger aber IMHO sollte es eine Basisklasse geben die alle Gemeinsamkeiten als Virtuals enthält, bei identischer Teil(Implementierung) bereits mit Code, die Implementierung für beide Kommunikationsvarianten kann nur in den Overrides der Ableitungen implementiert werden.
Ich würde also UDP nicht von ISDN ableiten sondern beide Klassen von einer gemeinsamen Basisklasse.
Aber vielleicht haben wir auch gerade einen Kommunikationsknoten....
_________________ Das Problem liegt üblicherweise zwischen den Ohren H₂♂
DRY DRY KISS
|
|
OlafSt 
      
Beiträge: 486
Erhaltene Danke: 99
Win7, Win81, Win10
Tokyo, VS2017
|
Verfasst: Fr 11.03.11 10:47
Guten Morgen, Freunde !
Heute früh habe ich mich diesem Problem wieder zugewandt. Ersteinmal Danke für die Mühe, mir bei diesem Problem zu helfen. Ich weiß das zu schätzen, haben wir doch alle in der Woche genug zu tun
Die Idee, sowohl ISDN als auch UDP von einer gemeinsamen Basisklasse abzuleiten, habe ich aufgegriffen und in meinem Mini-Beispiel versucht. Also gibt es nun eine TAnyClassBase, von der sowohl TAnyClass1 als auch TAnyClass2 abgeleitet werden. Ergebnis: The same.
Dann habe ich versucht TAnyClass2 von TAnyClass1 abzuleiten. Ergebnis: The same.
Ich habs mit nem Typecast versucht, falls der Compiler irgendwas verbaselt ((TA as TAnyClass1).GetFxValue). Ergebnis: The same.
Ich habe den Compiler gewechselt (D7 -> D2006). Ergebnis: The same.
Offenbar ist das, was ich da vorhabe, überhaupt nicht vorgesehen. Dann aber frage ich mich ernsthaft, wie alle meine Programme bisher funktionieren können (von der VCL mal ganz zu schweigen, ich sage nur Tag-Property in allen von TComponent abstammenden Klassen).
Ich bin für weitere Ideen immer zu haben.
_________________ Lies, was da steht. Denk dann drüber nach. Dann erst fragen.
|
|
|