delphi - 调用从接口(interface)和另一个祖先继承的类的方法

标签 delphi oop interface multiple-inheritance

我在实现某些类之间的关系时遇到问题。我有三个不同的类(class),服务于三种不同的形式。所有这些类都使用相同的语言,因此它们继承自同一个名为 TAncestorServer 的类。我们将其后代称为 TForm1ServerTForm2ServerTForm3ServerTAncestorServer 包含一个名为 Function1 的抽象方法,因此 TForm1TForm2TForm3可以通过从它继承的自己的类毫无问题地调用它,它们可以通过名为 Server 的属性访问这些类。但问题出在另一种名为 TForm4 的表单上!它与其他形式非常相似,但并不像它们那样独立。它与 TForm2ServerTForm3Server 配合使用。仍然不是问题,但想象一下在 TForm2ServerTForm3Server 中声明的另一个方法,例如 Function2TForm4 需要给他们打电话。我可以这样:

if Server is TForm2Server then
   TForm2Server(Server).Function2
else if Server is TForm3Server then
  TForm3Server(Server).Function2;

但它可以变成无限的 if-else 子句!所以我认为像多重继承这样的东西可能会有所帮助。我声明了一个名为 IForm4Server 的接口(interface),其中包含 Function2。因此,TForm2ServerTForm3Server 继承自 TAncestorServerIForm4Server。我认为这样的事情可以工作:

If Server is IForm4Server then
  IForm4Server(Server).Function2;

但是编译器不这么认为,它说这不是有效的类型转换,因为 TAncestorServer 不是 IForm4Server,这是绝对正确的。 TForm1Server 不知道如何实现 Function2,因此必须将其留空。我也无法将 TForm4.Server 声明为 IForm4Server,因为 Function1 代表大量方法和属性,但我仍然不能将 IForm4Server 类型转换为 TAncestorServer

作为解决方案,我可以在 TForm4 中定义两个不同的属性,例如 GeneralServer: TAncestorServerForm4Server: IForm4Server ,然后分配相同的 实例code>TForm2ServerTForm3Server 给他们,但我对此感觉不好。我该怎么做?有没有标准模式?

最佳答案

实现一个或多个接口(interface)是正确的方法,但看起来您对正确的语法有点困惑并且没有接口(interface)经验。

基本内容是:

  • 对于任意数量的类,您都有一个共同的祖先类(或形式)。祖先声明了类以某种方式专门化的虚拟方法。
  • 声明具有任意数量方法的接口(interface)。不要忘记向您的界面添加 GUID。
  • 扩展表单声明以实现声明的接口(interface),将接口(interface)添加到类声明中并添加声明的方法。
  • 您现在可以:
    • 使用祖先类多态调用任何虚拟方法
    • 询问任何表单是否实现了接口(interface),如果实现了,则检索对其的接口(interface)引用并调用任何接口(interface)方法。所有这一切都可以使用 supports 来完成功能。

我做了一个我能想到的最简单的例子,使用表单的视觉继承和一个简单的界面。该示例的摘录如下:

共同祖先类:

type
  TServerForm = class(TForm)
  private
    { Private declarations }
  public
    { Public declarations }
    procedure Method1; virtual;
  end;

界面:

type
  IMyInterface = interface
  ['{B7102C7E-F7F6-492A-982A-4C55CB1065B7}']
    procedure Method2;
  end;

子表单:

这个继承自TServerForm并实现了接口(interface)

type
  TServerForm3 = class(TServerForm, IMyInterface)
  public
    procedure Method1; override;
    procedure Method2;
  end;

这个只是继承自TServerForm

type
  TServerForm4 = class(TServerForm)
  public
    procedure Method1; override;
  end;

这个直接继承自TForm并实现了接口(interface)

type
  TNoServerForm = class(TForm, IMyInterface)
  public
    procedure Method2;
  end;

所有表单都是自动创建的,然后,我有以下代码来调用另一个表单(应用程序示例的主表单)上按钮的几个 OnClick 上的方法:

基于多态性调用虚方法:

procedure TForm6.Button1Click(Sender: TObject);
var
  I: Integer;
begin
  for I := 0 to Screen.FormCount - 1 do
  begin
    if (Screen.Forms[I] is TServerForm) then
      TServerForm(Screen.Forms[I]).Method1;
  end;
end;

根据接口(interface)的实现来调用方法:

procedure TForm6.Button2Click(Sender: TObject);
var
  I: Integer;
  Intf: IMyInterface;
begin
  for I := 0 to Screen.FormCount - 1 do
  begin
    if Supports(Screen.Forms[I], IMyInterface, Intf) then
      Intf.Method2;
  end;
end;

这些方法只显示消息,一切正常:

procedure TServerForm3.Method2;
begin
  ShowMessage(ClassName + '.Method2');
end;

关于delphi - 调用从接口(interface)和另一个祖先继承的类的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14990863/

相关文章:

c# - 接口(interface)类

delphi - 桌面 Delphi 应用程序是否可以通过 Windows 8 认证(使用 Windows 应用程序认证套件)?

delphi - TClientDataSets 的 'invalid field type' 错误我不明白

delphi - DScintilla 是否有语法突出显示的示例?

Delphi:引用由TAutoObjectFactory创建的类实例

opengl - opengl中的顶点缓冲区

java - 对通用接口(interface)列表进行排序

c++ - 如何在关键字 this 上调用重载的 () 运算符?

ios - 允许子类访问/覆盖函数,但不允许快速访问/覆盖同一模块中的任何其他类

c++ - 动态转换接口(interface)指针