鉴于以下界面:
ITest = interface ['guidhere']
procedure TestMethod;
end;
Run Code Online (Sandbox Code Playgroud)
是否有任何理由在实现类中TestMethod()声明为 as public?我已经把它放在private和protected部分,它似乎没有什么区别。我只是想知道是否有任何指导方针,从设计角度(或任何角度),使该public部分成为实现该方法的正确部分。
实现方法不在公共部分有关系吗?
就编译器而言。没有什么不同的。
话虽如此。私有方法仍然是私有的,即使您可以通过接口访问它们。
unit unit1;
....
IItest = interface
['{A3D5FEB6-8E29-4EA8-8DC9-7988294EFA65}']
procedure Test;
end;
TTest = class(TInterfacedObject, IItest)
private
procedure Test;
end;
unit unit2;
....
var
TestT: TTest;
TestI: ITest;
begin
TestT:= TTest.Create;
TestI:= TTest.Create;
TestT.Test; //will not compile.
TestI.Test; //works.
Run Code Online (Sandbox Code Playgroud)
这样做的原因是接口在其 VMT 中只有一个指向方法的指针列表。方法的定义在接口定义中给出。
编译器只检查签名是否匹配。
它不检查方法的可见性。
根据艾伦的评论,这是一个深思熟虑的设计:
将方法设为私有或受保护将确保您只能通过接口访问它们。这是一种为对象的预期用途强制执行使用合同的方法。
请注意,这不是错误,甚至不是坏事。
属性也可以“访问”私有方法:
property Items[index: integer] read GetItem write SetItem;
Run Code Online (Sandbox Code Playgroud)
这里的 GetItem 和 SetItem 通常是私有的。
这会强制您使用该属性访问 Items。
使用属性时,实现方法通常是受保护的(或更糟的是:-)。相同的逻辑适用于属性和接口。
接口更是如此,因为如果您混合接口访问和常规访问,您将遇到引用计数问题。
干净的代码
请注意,您可以在类标题中拥有任意数量的可见性部分。
通过这种方式,您可以将所有接口方法放在一个部分,而将所有非接口方法放在另一个部分。
TTest = class(TInterfacedObject, I1, I2)
//I1 methods
private
... private I1 methods here...
protected
.. more I1 methods
//I2 methods
private
.. some I2 methods
protected
..more I2 methods
//TTest methods
private
//data members
public
constructor Create;
destructor Destroy; override;
end;
Run Code Online (Sandbox Code Playgroud)
这样就可以清楚地知道什么是什么。