Raf*_*olo 4 delphi oop properties interface
当我们在Delphi中设计一个类时,通常我们有私有字段(成员),私有setter和getter方法以及公共属性.从课外,该数据的访问仅由公共财产进行; 该类的用户甚至不知道存在getter方法.
因此getter和setter方法封装了实例成员,属性封装了getter和setter方法.
但是,在定义接口时,我们将公开这些方法:
ICounter = interface
// I wouldn't want to specify these 2 methods in the interface, but I'm forced to
function GetCount: Integer;
procedure SetCount(Value: Integer);
property Count: Integer read GetCount write SetCount;
end;
Run Code Online (Sandbox Code Playgroud)
实现具体类:
TCounter = class(TInterfacedObject, ICounter)
private
function GetCount: Integer;
procedure SetCount(Value: Integer);
public
property Count: Integer read GetCount write SetCount;
end
Run Code Online (Sandbox Code Playgroud)
使用它:
var
Counter: ICounter;
begin
Counter := TCounter.Create;
Counter.Count := 0; // Ok, that's my public property
// The access should me made by the property, not by these methods
Counter.SetCount(Counter.GetCount + 1);
end;
Run Code Online (Sandbox Code Playgroud)
如果属性封装了getter/setter私有方法,这不是违规吗?吸气剂和固定剂是具体类的内部,不应暴露.
方法是与接口交互的主要方式.接口上的属性是特定于Delphi的扩展; 他们只为基础方法提供语法糖.没有其他语言由于接口中的方法定义为public,因此它们不会被属性封装.您不会通过显示属性由方法支持来揭示任何实现细节,因为在接口中,属性始终由方法支持,并且方法始终是公共的.如果首先从不存在封装,则不能违反封装.
您的示例具体类具有误导性.首先,在那里定义的属性与接口中定义的属性完全没有关联.您可以将其定义为只读,使其直接访问数据成员,使其成为私有,或以任何其他方式与接口版本不同,包括完全删除它,并且它对接口的用户没有任何影响,进一步借出相信它是接口中重要的方法,而不是属性.编译器将接口属性的任何使用直接转换为使用已公开的相应接口方法之一.在这个问题上从不咨询实施对象.
其次,类上的可见性说明符是无关紧要的.没有必要将这些方法设为私有,因为它们已经在接口上公开了.但是,将它们设为私有并不是一个坏主意,因为它鼓励通过界面正确使用类.
您可以抱怨接口的访问器方法应该是私有的,但这与要求接口方法通常能够是私有的相同,这是没有意义的.显然不能调用的方法不是接口的一部分.回想一下,任何支持COM的语言都可以使用接口,即使是那些没有属性概念的语言,比如C和C++.这些语言也需要能够调用访问器方法.如果这些方法是私有的,那么界面将不适用于这些语言.
当Delphi类的属性引用字段时,该细节实际上是类的面向公众的接口的一部分.任何使用该属性的代码都知道该属性只是该字段的别名(即使代码的作者不知道).如果更改属性定义,则需要重新编译使用该类的任何代码,以便编译器可以生成用于访问属性的新代码.
当需要方法支持属性时,您无法再真正更改属性定义.只有实现可以更改,因此接口的任何消费者都不需要重新编译,因为您选择按需计算属性而不是从存储的字段中读取.