简体   繁体   English

在Delphi中实现接口时,实现方法不在公共部分有关系吗?

[英]When implementing an interface in Delphi, does it matter if the implementation methods are not in the public section?

Given the interface below:鉴于以下界面:

ITest = interface ['guidhere']
  procedure TestMethod;
end;

Is there any reason to have TestMethod() declared as public in the implementation class?是否有任何理由在实现类中将TestMethod()声明为public I have put it in both the private and protected sections and it does not seem to make a difference.我已经把它放在privateprotected部分,它似乎没有什么区别。 I am just wondering if there are any guidelines, from a design perspective (or any perspective really), that make the public section the correct section to implement the method in.我只是想知道是否有任何指导方针,从设计角度(或任何角度),使public部分成为实现该方法的正确部分。

does it matter if the implementing methods are not in the public section?如果实施方法不在公共部分,那么重要吗?

As far as the compiler is concerned.就编译器而言。 It makes no difference.这没什么区别。

That being said.话虽如此。 Private methods will still be private, even if you can access them through the interface.私有方法仍然是私有的,即使您可以通过接口访问它们。

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.

The reason for this is that the interface simply has a list of pointers to methods in its VMT.这样做的原因是接口在其 VMT 中只有一个指向方法的指针列表。 The definition of the method is given in the interface definition.方法的定义在接口定义中给出。
The compiler only checks if the signatures match.编译器只检查签名是否匹配。
It does not check the visibility of the method.它不检查方法的可见性。

As per Allen's comment this is a deliberate design:根据艾伦的评论,这是一个深思熟虑的设计:

Making the methods private or protected will ensure that you can only access them through the interface.将方法设为私有或受保护将确保您只能通过接口访问它们。 This is a way to enforce a usage contract for the intended use of the object.这是一种为对象的预期用途强制执行使用合同的方法。

Note that this is not an error, or even a bad thing.请注意,这不是错误,甚至不是坏事。
Properties can give 'access' to private methods as well:属性也可以“访问”私有方法:

property Items[index: integer] read GetItem write SetItem;  

Here GetItem and SetItem are often private.这里的 GetItem 和 SetItem 通常是私有的。
This forces you to access the Items using the property.这会强制您使用该属性访问 Items。
When using properties the implementing methods are protected (or worse :-) as a rule.使用属性时,实现方法通常是受保护的(或更糟的是:-)。 The same logic applies to both properties and interfaces.相同的逻辑适用于属性和接口。

More so for interfaces, because if you mix interface access and regular access you'll run into reference counting issues.接口更是如此,因为如果您混合接口访问和常规访问,您将遇到引用计数问题。

Clean code干净的代码
Note that you can have as many visibility sections in a class header as you like.请注意,您可以根据需要在类标题中拥有任意数量的可见性部分。
This way you can put all the interfaced methods in one part and all the non-interfaced methods in another.通过这种方式,您可以将所有接口方法放在一个部分,而将所有非接口方法放在另一个部分。

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;

That way it's as clear as can be what's what.这样就可以清楚地知道什么是什么。

I appreciate this is an old question, but the answer is no longer accurate.我很欣赏这是一个老问题,但答案不再准确。

I am using Rio, and from the documentation :我正在使用 Rio,并且来自文档

All members of an interface are public.接口的所有成员都是公共的。 Visibility specifiers and storage specifiers are not allowed.不允许使用可见性说明符和存储说明符。 (But an array property can be declared as default.) (但可以将数组属性声明为默认值。)

which is indeed what I observe.这确实是我观察到的。 An interface defitnion will not allow protected, private or public to be specified.接口定义不允许指定protected、private 或public。


Edit: To incorporate comments to this answer编辑:将评论合并到此答案中

At the time of writing the compiler does not enforce any level of visibility on the methods which implement the interface.在撰写本文时,编译器并未对实现接口的方法强制实施任何级别的可见性。 The methods will be callable through either the interface (interface reference) or through the class (object instance).这些方法可以通过接口(接口引用)或类(对象实例)调用。

As the interface definition insists that all methods are public, when called through an interface reference the implementing methods are public regardless of how they are defined in the implementing class.由于接口定义坚持所有方法都是公共的,因此当通过接口引用调用时,实现方法是公共的,无论它们在实现类中是如何定义的。 As a reference to the interface can be obtained from the object then they are callable from the object, although the caller may have to obtain the interface reference first.由于可以从对象中获取对接口的引用,因此它们可以从对象中调用,尽管调用者可能必须首先获取接口引用。

Given that the implementing methods are callable as public through the interface you should consider how helpful it is to not make them public in your class.鉴于实现方法可以通过接口公开调用,您应该考虑在您的类中不公开它们有多大帮助。 Restricting the visibility of the methods in the class when they are public in the interface seems to me to be making the code less clear, but other opinions are available!限制类中方法在接口中公开时的可见性在我看来使代码不太清晰,但其他意见也可用!

One of the comments mentioned delegation of the interface.评论之一提到了接口的委托。 This seems to me to be a distraction as it simply means that when the object retruns the interface reference it returns the reference from the delgated object (which could itself delegate the interface) and ultimately it is the methods of that object whaich are called.这在我看来是一种干扰,因为它只是意味着当对象重新运行接口引用时,它返回来自委托对象(它本身可以委托接口)的引用,并且最终调用的是该对象的方法。

So any class which implements an interface makes the methods which implement the interface available as public when called through the interface.因此,任何实现接口的类都会使实现接口的方法在通过接口调用时作为公共可用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM