5

我在实现某些类之间的关系时遇到问题。我得到了三个不同的课程,提供三种不同的形式。所有这些类都使用同一种语言,因此它们都继承自同一个名为TAncestorServer. 让我们称其后代TForm1Server为 ,TForm2ServerTForm3ServerTAncestorServer包含一个名为Function1, so TForm1,的抽象方法TForm2,并且TForm3可以通过继承自它的自己的类毫无问题地调用它,他们可以通过名为 的属性访问这些类Server。但问题在于另一种形式,称为TForm4!它与其他形式非常相似,但不像它们那样独立。它适用于TForm2Serveror TForm3Server。仍然不是问题,但想象一下另一种方法,例如在和Function2中声明的TForm2ServerTForm3ServerTForm4需要打电话给他们。我可以这样走:

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

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

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

但是编译器不这么认为,它说它不是有效的类型转换,因为TAncestorServeris not IForm4Server,这是绝对正确的。TForm1Server对实施一无所知Function2,必须将其留空。我也不能这样声明,因为TForm4.Server它代表了大量的方法和属性,但是我仍然不能将类型转换为.IForm4ServerFunction1IForm4ServerTAncestorServer

作为一种解决方案,我可以在TForm4like中定义两个不同的属性GeneralServer: TAncestorServerForm4Server: IForm4Server然后为它们分配相同的TForm2Serveror实例TForm3Server,但我对此感觉不好。我该怎么做?它有什么标准模式吗?

4

1 回答 1

6

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

基本的东西是:

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

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

共同祖先类:

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,实现接口

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

这个只是继承自 TServerForm

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

而这个直接继承自TForm并实现接口

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

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

调用基于多态的虚方法:

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;

调用基于接口实现的方法:

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;
于 2013-02-20T22:51:19.113 回答