【发布时间】:2012-12-07 23:49:08
【问题描述】:
我使用 Delphi 2006,我有一个名为 TMyClassTest 的复杂类,它有很多方法
其中一些方法创建非可视组件并分配这些组件的事件处理程序并运行这些组件的方法。
我还有两个实现相同接口的类,如下所示:
TMyClass1 = class(Class1, Interface1)
... //procedures from the Interface1
procedure MyClass1Proc1;
end;
TMyClass2 = class(Class2, Interface1)
... //procedures from the Interface1
procedure MyClass2Proc1;
procedure MyClass2Proc2
end;
现在我也需要 TMyClass1 和 TMyClass2 来“继承” TMyClassTest。 更多... Interface1 必须包含(除了它的方法之外)来自 MyClassTest 的所有方法。 如何避免在两个类(TMyClass1 和 TMyClass2)上实现(如复制/粘贴) TMyClassTest 的所有程序? 我不想在三个不同的地方保留相同的代码。
基于 Arioch 的 cmets,我创建了一个解决方案,例如: (见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;
因为我在MyClass.FMyImplClass := TMyImplClass.Create; 有一个错误,所以我尝试创建FMyImplClass 从TMyClass1 和TMyClass2 声明构造函数,但不能正常工作。
还有其他方法可以创建FMyImplClass 吗?
现在我尝试了一个似乎可以正常工作的解决方案。会不会有一些隐藏的影响?
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;
【问题讨论】:
-
1) 使 Class1 和 Class2 继承自 TMYClassTest 或 2) 使 TmyClassX 不再直接实现 Interface1,而是将它们添加到 TMyClassTest 字段并将它们的 Interface1 委托到该字段
-
你运气不好。 Delphi 不做多重继承。另一方面,继承是一种严重过度使用和误用的工具。把这当作组合是要走的路的标志。
-
Class1 不是我的班级,无法更改任何内容。
-
@sorin 为“delphi 接口委托”做 Google 将其显示为顶部链接:stackoverflow.com/questions/3483680 我认为您最好将新的常用函数移入某个 Interface0 类型,并使 Interface1 成为 Interface0 的子项.然后你创建一些 TMyClasssBaseCommonTrait 类,实现 Interface0,以及两个子类 TMyClass1InternalEngine(TMyClasssBaseCommonTrait) 和 TMyClass2InternalEngine(TMyClasssBaseCommonTrait) 实现(以不同的,TMyClassX-specific 方式,Interface1(Interface0) API 的其余部分 /// Delphi 没有类似 Scala特征或类似 Py 的 mixins
标签: delphi oop class inheritance interface