【问题标题】:How to inherit another class when a class already extend a class and an Interface当一个类已经扩展了一个类和一个接口时如何继承另一个类
【发布时间】: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; 有一个错误,所以我尝试创建FMyImplClassTMyClass1TMyClass2 声明构造函数,但不能正常工作。 还有其他方法可以创建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


【解决方案1】:

Delphi 没有类似 Scala 的特征或类似 Python 的 mixin,也不支持像 C++ 那样的多重继承。

如果你不能让Class1Class2 继承自TMyClassTest,那么也许你必须依赖接口委托:让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实实现

“delphi 接口委托”的 Google 将其显示为顶部链接:Delphi: How delegate interface implementation to child object?

【讨论】:

    猜你喜欢
    • 2023-03-14
    • 2016-02-28
    • 1970-01-01
    • 1970-01-01
    • 2014-11-22
    • 2019-05-22
    • 2011-01-04
    • 2011-10-19
    相关资源
    最近更新 更多