当类已经扩展了类和接口时,如何继承另一个类

时间:2012-12-20 12:43:03

标签: delphi oop class inheritance interface

我使用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中的所有方法。 如何避免在两个clases(TMyClass1和TMyClass2)上实现(如复制/粘贴)TMyClassTest中的所有过程? 我不想在三个不同的地方保留相同的代码。

根据Arioch的评论,我创建了一个解决方案: (见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;时遇到错误,我尝试从FMyImplClassTMyClass1创建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 个答案:

答案 0 :(得分:3)

Delphi没有类似Scala的特性或类似Python的mixins,也不支持C ++的多重继承。

如果您无法从Class1继承Class2TMyClassTest,那么您可能必须依赖接口委派:make TMyClassX否更多地直接实施Interface1,而是为其添加TMyClassTest字段,并将其Interface1委托给此字段。

我认为你会更好

  1. 将这些新常用功能移至某些Interface0类型
  2. 使Interface1继承自Interface0
  3. 制作一些TMyClassesBaseCommonTrait课程,实施Interface0
  4. 使两个子类TMyClass1InternalEngine(TMyClassesBaseCommonTrait)TMyClass2InternalEngine(TMyClassesBaseCommonTrait)实现(以不同的TMyClassX - 特定方式实现Interface1(Interface0) API的其余部分
  5. TMyClassX类内部私有字段TMyClass2InternalEngine类型doign real implemntation
  6. 谷歌的“delphi界面委派”将此显示为顶部链接:Delphi: How delegate interface implementation to child object?