Reputation: 23
I work with Delphi 2006 and I have a complex class named TMyClassTest
that have many methods
Some of those methods create nonvisual components and assign event handlers of those components and run methods of those components.
Also I have two classes that implement the same interface like below:
TMyClass1 = class(Class1, Interface1)
... //procedures from the Interface1
procedure MyClass1Proc1;
end;
TMyClass2 = class(Class2, Interface1)
... //procedures from the Interface1
procedure MyClass2Proc1;
procedure MyClass2Proc2
end;
Now I need that TMyClass1 and TMyClass2 to 'inherit' the TMyClassTest, too. Much more ... Interface1 must contain (beyond its methods) all the methods from the MyClassTest. How can I avoid to implement (like copy/paste) on both clases (TMyClass1 and TMyClass2) all the procedures from TMyClassTest ? I don't want to keep the same code on three separate places.
Based on Arioch's comments I created a solution like: (see http://docwiki.embarcadero.com/RADStudio/XE3/en/Implementing_Interfaces#Implementing_Interfaces_by_Delegation_.28Win32_only.29)
type
IMyInterface = interface
procedure P1;
procedure P2;
end;
TMyImplClass = class
procedure P1;
procedure P2;
end;
TMyClass1 = class(Class1, IMyInterface)
FMyImplClass: TMyImplClass;
property MyImplClass: TMyImplClass read FMyImplClass implements IMyInterface;
procedure IMyInterface.P1 = MyP1;
procedure MyP1;
end;
TMyClass2 = class(TInterfacedObject, IMyInterface)
FMyImplClass: TMyImplClass;
property MyImplClass: TMyImplClass read FMyImplClass implements IMyInterface;
procedure P3;
procedure P4;
end;
procedure TMyImplClass.P1;
// ...
procedure TMyImplClass.P2;
// ...
procedure TMyClass1.MyP1;
// ...
procedure TMyClass2.P3;
// ...
procedure TMyClass2.P4;
// ...
var
MyClass: TMyClass1;
MyInterface: IMyInterface;
begin
MyClass := TMyClass1.Create;
MyClass.FMyImplClass := TMyImplClass.Create; //Error !!!! FMyImplClass is a read only property !!!
MyInterface := MyClass;
MyInterface.P1; // calls TMyClass1.MyP1;
MyInterface.P2; // calls TImplClass.P2;
end;
Because I have an error at MyClass.FMyImplClass := TMyImplClass.Create;
I tried to create FMyImplClass
declaring constructor from TMyClass1
and TMyClass2
but don't work ok.
Is there some other method to create FMyImplClass
?
Now I tried a solution that seem to work ok. Can there happen some hidden efects?
type
IMyInterface = interface
procedure P1;
procedure P2;
procedure CreateFMyImplClass;
end;
TMyImplClass = class
procedure P1;
procedure P2;
end;
TMyClass1 = class(Class1, IMyInterface)
FMyImplClass: TMyImplClass;
property MyImplClass: TMyImplClass read FMyImplClass implements IMyInterface;
procedure IMyInterface.P1 = MyP1;
procedure MyP1;
procedure CreateFMyImplClass;
end;
TMyClass2 = class(TInterfacedObject, IMyInterface)
FMyImplClass: TMyImplClass;
property MyImplClass: TMyImplClass read FMyImplClass implements IMyInterface;
procedure P3;
procedure P4;
procedure CreateFMyImplClass;
end;
procedure TMyImplClass.P1;
// ...
procedure TMyImplClass.P2;
// ...
procedure TMyClass1.MyP1;
// ...
procedure TMyClass1.CreateFMyImplClass;
begin
FMyImplClass := TMyImplClass.Create;
end;
procedure TMyClass2.P3;
// ...
procedure TMyClass2.P4;
// ...
procedure TMyClass2.CreateFMyImplClass;
begin
FMyImplClass := TMyImplClass.Create;
end;
var
MyInterface: IMyInterface;
begin
if WantRemote then
MyInterface := TMyClass1.Create
else
MyInterface := TMyClass2.Create;
MyInterface.CreateFMyImplClass; // create FMyImplClass ;
MyInterface.P2; // calls TImplClass.P2;
end;
Upvotes: 2
Views: 1292
Reputation: 16045
Delphi does not have Scala-like traits or Python-like mixins, nor it support multiple inheritance a la C++.
If you cannot make Class1
and Class2
inherit from TMyClassTest
, then perhaps you have to rely on interface delegation: make TMyClassX
no more implementing Interface1
directly, but instead add them a field of TMyClassTest
and delegate their Interface1
to this field.
I think you'd better
Interface0
typeInterface1
inherited from Interface0
TMyClassesBaseCommonTrait
class, implementing Interface0
TMyClass1InternalEngine(TMyClassesBaseCommonTrait)
and TMyClass2InternalEngine(TMyClassesBaseCommonTrait)
implementing (in different, TMyClassX
-specific ways, the rest of Interface1(Interface0)
APITMyClassX
classes internal private field of TMyClass2InternalEngine
type doign real implemntationGoogle for "delphi interface delegation" shows this as top link: Delphi: How delegate interface implementation to child object?
Upvotes: 3