我在实现某些类之间的关系时遇到问题。我有三个不同的课程,提供三种不同的形式。所有这些类都使用相同的语言,因此它们继承自同一个类TAncestorServer
。我们称其后代为TForm1Server
,TForm2Server
和TForm3Server
。 TAncestorServer
包含一个名为Function1
的抽象方法,因此TForm1
,TForm2
和TForm3
可以通过自己继承的类来调用它,没有问题,可以通过名为Server
的属性访问类。但问题在于另一种称为TForm4
的形式!它与其他形式非常相似,但它并不像他们那样独立。它适用于TForm2Server
或TForm3Server
。仍然不是问题,但想象一下Function2
和TForm2Server
中声明的TForm3Server
之类的另一种方法,TForm4
需要调用它们。我可以这样:
if Server is TForm2Server then
TForm2Server(Server).Function2
else if Server is TForm3Server then
TForm3Server(Server).Function2;
但它可以变成一个无限的if-else子句!所以我认为像多重继承这样的东西可能会有所帮助。我声明了一个名为IForm4Server
的接口,其中包含Function2
。因此,TForm2Server
和TForm3Server
都会继承TAncestorServer
和IForm4Server
。我认为这样的事情可行:
If Server is IForm4Server then
IForm4Server(Server).Function2;
但是编译器不这么认为,它说它不是有效的类型转换,因为TAncestorServer
不是IForm4Server
,这是绝对正确的。 TForm1Server
无法实施Function2
,并且必须将其留空。我也无法将TForm4.Server
声明为IForm4Server
,因为Function1
代表了大量的方法和属性,但我仍然无法将IForm4Server
类型转换为{{1} }}
作为一种解决方案,我可以在TAncestorServer
TForm4
和GeneralServer: TAncestorServer
中定义两个不同的属性,然后为其分配Form4Server: IForm4Server
或TForm2Server
的相同实例,但我感觉不太好。我该怎么做?它有什么标准模式吗?
答案 0 :(得分:6)
实现一个或多个接口是正确的方法,但看起来你对正确的语法有点困惑,并且没有接口经验。
基本的事情是:
我做了一个我能想到的最简单的例子,使用视觉继承表单和简单的界面。该示例的摘录如下:
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
上的方法,用于另一个表单上的按钮(应用程序示例的主要形式):
基于多态性调用虚方法:
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;