![]() |
Vererbung mit mehrfach eingeschränktem TypParamater
Hallo,
ich möchte eine Klasse mit zweifach eingeschränktem TypParameter nach der Art TFoo<T: Interface1,Interface2> vererben. Die Klasse0, ist die Klasse mit den zwei einschränkenden TypParametern. An Klasse1 soll nun Klasse0 mit dem InterfaceTypParameter IKlasse1 vererbt werden. Bekomme aber die Fehlermeldung [dcc32 Fehler] : E2514 Typparameter 'T' muss Interface 'IKlasse2' unterstützen Was ist falsch? interface type IKlasse1 = interface; IKlasse2 = interface; Klasse0< T : IKlasse1, IKlasse2 > = class; Klasse1 = class; Klasse2 = class; IKlasse1 = interface end; IKlasse2 = interface end; Klasse0< T : IKlasse1, IKlasse2 > = class(TInterfacedObject) function Transform : T; end; Klasse1 = class( Klasse0< IKlasse1 > ) end; ===>> hier erfolgt die Fehlermeldung: Typparameter 'T' muss Interface 'IKlasse2' unterstützen Klasse2 = class( Klasse0< IKlasse2 > ) end; ===>> hier erfolgt die Fehlermeldung: Typparameter 'T' muss Interface 'IKlasse1' unterstützen implementation end. Gruß Alexander |
AW: Vererbung mit mehrfach eingeschränktem TypParamater
Naja die Typeinschränkungen müssen halt beide erfüllt werden.
Delphi-Quellcode:
=>
Klasse0< T : IKlasse1, IKlasse2 > = class;
T muss IKlasse1 UND IKlasse2 unterstützen. Nicht ODER. Du solltest deinen Code übrigens mit Delphi-Tags versehen. Das machts etwas übersichtlicher! |
AW: Vererbung mit mehrfach eingeschränktem TypParamater
Und ohne die Forward-Deklarationen sieht der Code auch gleich viel übersichtlicher aus. :angel:
Delphi-Quellcode:
Ich hätte zwar auch ODER gedacht, aber wenn das stimmt, dann kannst du das vielleicht über eine Interfacevererbung lösen:
interface
type IKlasse1 = interface end; IKlasse2 = interface end; Klasse0<T: IKlasse1, IKlasse2> = class(TInterfacedObject) function Transform: T; end; Klasse1 = class(Klasse0<IKlasse1>) end; Klasse2 = class(Klasse0<IKlasse2>) end; implementation end.
Delphi-Quellcode:
Oder du schränkst es nicht all zu sehr ein:
type
IBasisKlasse = interface end; IKlasse1 = interface(IBasisKlasse) end; IKlasse2 = interface(IBasisKlasse) end; Klasse0<T: IBasisKlasse> = class(TInterfacedObject) // oder Klasse0<T: IBasisKlasse> = class(TInterfacedObject, IBasisKlasse) function Transform: T; end; Klasse1 = class(Klasse0<IKlasse1>) end; Klasse2 = class(Klasse0<IKlasse2>) end;
Delphi-Quellcode:
[edit]
type
IKlasse1 = interface end; IKlasse2 = interface end; Klasse0<T: interface> = class(TInterfacedObject) function Transform: T; end; Klasse1 = class(Klasse0<IKlasse1>) end; Klasse2 = class(Klasse0<IKlasse2>) end; Ich mein natürlich IKlasse0, statt IBasisKlasse :angle: |
AW: Vererbung mit mehrfach eingeschränktem TypParamater
Danke für die schnellen Antworten.
Ich hatte gedacht, gehofft das man sagen kann das für T entweder die eine oder andere IKlasse gilt. Probiert hatte ich auch IKlasse1 = interface(IUnknown) end; IKlasse2 = interface(IUnknown) end; Klasse0<T : IKlasse1, IKlasse2> = class(TInterfacedObject) function Transform : T; end; Klasse1 = class( Klasse0< IKlasse1 , IKlasse2> ) end; mit FehlerMeldung [dcc32 Fehler] E2003 Undeklarierter Bezeichner: 'Klasse0<,>' jetzt hätte ich gedacht das beide IKlassen angenommen werden. Gruß Alexander |
AW: Vererbung mit mehrfach eingeschränktem TypParamater
Einschränkungen für Typparameter können kein "oder". Alles was du hinter dem ":" angibst, muss restlos erfüllt sein.
|
AW: Vererbung mit mehrfach eingeschränktem TypParamater
Aso, deswegen heißt es also
Delphi-Quellcode:
E2553 Klassentypeinschränkung darf nicht mehr als einmal angegeben werden
|
AW: Vererbung mit mehrfach eingeschränktem TypParamater
Zitat:
Das ist manchmal ein bisschen niggelich, wenn man z.B. eine Generische Klasse oder Methode bauen will, die für Klassen und Interfaces geht, aber nicht für andere Datentypen. Dann muss man die unterschiedlich nennen. |
AW: Vererbung mit mehrfach eingeschränktem TypParamater
Hallo,
was muß ich an der Zeile ändern, damit der Compiler keinen Fehler anzeigt. Hab schon etliches ausprobiert aber leider keinen Treffer gelandet. Klasse1 = class( Klasse0< IKlasse1 , IKlasse2> ) end; ==> FehlerMeldung [dcc32 Fehler] E2003 Undeklarierter Bezeichner: 'Klasse0<,>' Gruß Alexander |
AW: Vererbung mit mehrfach eingeschränktem TypParamater
Du hast
So geht es (aber ich weiß nicht, ob es das ist, was du willst)
Delphi-Quellcode:
program dp_180380;
{$APPTYPE CONSOLE} {$R *.res} uses System.SysUtils; type IKlasse1 = interface ['{E90AABBF-1711-4E09-AD38-63A6F53C2DBA}'] end; IKlasse2 = interface ['{8D8349B5-F5C2-4F85-9DAC-606D7307667A}'] end; TKlasse0<T : IKlasse1, IKlasse2> = class( TInterfacedObject ) end; TKlasse = class( TInterfacedObject, IKlasse1, IKlasse2 ) end; TKlasse1 = class( TKlasse0<TKlasse> ) end; begin try { TODO -oUser -cConsole Main : Code hier einfügen } except on E : Exception do Writeln( E.ClassName, ': ', E.Message ); end; end. |
AW: Vererbung mit mehrfach eingeschränktem TypParamater
Danke für die Tips.
Mich stört das ich eine Klasse haben muß, in der beide Interfaces auch noch implementiert werden müßen.
Delphi-Quellcode:
.
TKlasse = class( TInterfacedObject, IKlasse1, IKlasse2 )
Das wollte ich aber vermeiden. Ich möchte in TKlasse1 nicht auf IKlasse2 zugreifen können. Was man machen könnte wäre
Delphi-Quellcode:
.
TKlasse1 = class( TKlasse0<TKlasse> , IKlasse1 ) end;
Dann hätte ich aber doppelten Code, auch wenn ich in TKlasse virtual und abstract auf die Methoden von IKlasse1 lege. Nichts desto trotz, mein Ziel wäre gewesen in
Delphi-Quellcode:
auf die Methoden und Eigenschaften von element zugriefen zu können (element.Eigenschaft1) . Aber das geht leider nicht.
Klasse0<T : IKlasse1, IKlasse2> = class(TInterfacedObject)
function Transform(element : T) : T; end; Oder doch? Gruß und Danke Alexander |
AW: Vererbung mit mehrfach eingeschränktem TypParamater
Ich komme nicht ganz hinterher, was letztendlich dein Ziel ist.
Du hast zwei vollkommen verschiedene Interfaces. Eine Klasse soll jetzt entweder mit IMeinInterface1 ODER IMeinInterface2 parametrisiert werden können. Typeinschränkungen sind immer UND. Entweder es macht Sinn und du bildest ein gemeinsames Über-Interface (welches fortan die einzige Parametrisierungs-Einschränkung ist)
Delphi-Quellcode:
Oder es ist sicher dass es immer bei diesen beiden Interfaces bleiben wird. Dann würde ich die Klasse überhaupt nicht generisch machen sondern halt zwei verschiedene Methoden anbieten- Einmal für
type
IMyBaseInterface = interface // ? end; IMyInterface1 = interface(IMyBaseInterface) // ? end; IMyInterface2 = interface(IMyBaseInterface) // ? end; TMeineGenerischeKlasse<T: IMyBaseInterface> = class end;
Delphi-Quellcode:
und einmal für
IMyInterface1
Delphi-Quellcode:
.
IMyInterface2
Vielleicht liegt es an mir, aber ich persönlich habe immer große Schwierigkeiten mit vollkommen abstrakten Bezeichnern wie
Delphi-Quellcode:
. Kannst du vlt. ein ganz konkretes Beispiel geben? Kann ja frei erfunden sein, aber irgendwas zum "Anfassen"...
TKlasse1 = class( TKlasse0<TKlasse> , IKlasse1 ) end;
|
AW: Vererbung mit mehrfach eingeschränktem TypParamater
Zitat:
Mir scheint, deine OOP-Überlegungen bedürfen einer gründlicher Überarbeitung. Zitat:
Zitat:
|
AW: Vererbung mit mehrfach eingeschränktem TypParamater
Liste der Anhänge anzeigen (Anzahl: 1)
Ich hab mal ein pdf erstellt, in dem "ersichtlich" ist wie ich mir das gedacht habe.
Es gibt zwei verschiedene Klassen: Punkte und Vektoren. Dies erben von einer "abstrakten" BaseTransformationsKlasse die nix kann außer eine Instanz der TranslateKlasse in ihrer eigenen Methode BaseTransformations.Translate zu instanziieren. Die TranslateKlasse soll aber von Anfang an wissen welchem Typ sie erwarten soll, damit ich auf die Propertys zugreifen kann, nämlich element.X. In C# gibts sowas mit where T : .... und da kann man auf Methoden und Propertys sofort zugreifen. Gruß Alexander |
AW: Vererbung mit mehrfach eingeschränktem TypParamater
Warum nimmst du nicht einfach IBase als gemeinsamen Vorfahrtyp anstatt der beiden abgeleiteten Interfaces?
Delphi-Quellcode:
BaseTransformation<T: IBase>
Translate<T: IBase> |
AW: Vererbung mit mehrfach eingeschränktem TypParamater
Noch ohne auf die PDF geschaut zu haben: Das
Delphi-Quellcode:
in C# ist bei den Typeinschränkungen doch auch nichts anderes als der Doppelpunkt in Delphi. Und statt
where
Delphi-Quellcode:
heißt es
new()
Delphi-Quellcode:
.
constructor
Code:
bedeutet in C# doch genauso, dass T beide Interfaces implementieren muss.
public void meineMethode<T>(T meinParameter) where T: ISomeBaseInterface, ISomeOtherInterface
PS: Punkte und Vekoren. Ich wusste es :-D PPS: Warum überhaupt der Unterschied zwischen Punkten und Vektoren? Transformation wie bspw. Translation wird ja sowieso eigentlich doch über einen Vektor in homogenisierter Form mit einer Transformationsmatrix erledigt. Darüber lassen sich alle möglichen Operationen abwickeln. Aber das führt jetzt nur vom eigentlichen Thema weg... (oder?) PPPS: Warum möchtest du an der Stelle wissen, ob es nun ein IPoint oder IVector ist? Die richtige Typeinschränkung an diesen Fall wäre übrigens, anders als auf der PDF, IBase und nicht IPoint UND IVector. Wenn du jetzt zur Laufzeit unbedingt wissen willst ob es nun ein IPoint oder IVector ist kannst du das mit
Delphi-Quellcode:
überprüfen.
Supports(..)
Delphi-Quellcode:
program Project3;
{$APPTYPE CONSOLE} {$R *.res} uses System.SysUtils; type IBaseInterface = interface // end; IChildInterface1 = interface(IBaseInterface) ['{65F8AA65-0EED-4D26-A396-26999CD9E316}'] // end; IChildInterface2 = interface(IBaseInterface) ['{8F390B34-CCF6-4908-B205-D4CD9CF5D3BE}'] // end; TIChildClass1 = class(TInterfacedObject, IBaseInterface, IChildInterface1) // Es müssen IBaseInterface UND IChildInterface1 angegeben werden. // Ja, IBaseInterface ist eigentlich obsolet, aber so ist Delphi halt // Stört mich ehrlich gesagt auch end; TIChildClass2 = class(TInterfacedObject, IBaseInterface, IChildInterface2) // end; TSomeRecord = record public class procedure someMethod<T: IBaseInterface>(const someInput: T); static; end; { TSomeRecord } class procedure TSomeRecord.someMethod<T>(const someInput: T); begin if Supports(someInput, IChildInterface1) then WriteLn('Es ist ein IChildInterface1') else if Supports(someInput, IChildInterface2) then WriteLn('Es ist ein IChildInterface2') ; end; begin try TSomeRecord.someMethod( TIChildClass2.Create() ); except on E: Exception do Writeln(E.ClassName, ': ', E.Message); end; ReadLn; end. PPPPS: Generics und im Nachhinein wieder aufdröseln um im Detail nochmal zu schauen was drinsteckt führt Generics ad absurdum. So meine Meinung ohne gründlich drüber nachgedacht zu haben. |
AW: Vererbung mit mehrfach eingeschränktem TypParamater
Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 13:45 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