delphi - 它是否违反了接口(interface)属性访问器公开的封装?

标签 delphi oop properties interface

当我们在 Delphi 中设计一个类时,通常我们有私有(private)字段(成员)、私有(private) setter 和 getter 方法以及公共(public)属性。从类外部,只能通过公共(public)属性访问该数据;该类的用户甚至不知道 getter 方法的存在。

所以getter和setter方法封装了实例成员,属性封装了getter和setter方法。

但是,在定义接口(interface)时,我们公开了这些方法:

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;

实现具体类:

TCounter = class(TInterfacedObject, ICounter)
private
  function GetCount: Integer;
  procedure SetCount(Value: Integer);
public
  property Count: Integer read GetCount write SetCount;
end

使用它:

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;

如果属性封装了getter/setter私有(private)方法,这不是违规吗? getter 和 setter 是具体类的内部结构,不应公开。

最佳答案

方法是与界面交互的主要方式。接口(interface)上的属性是 Delphi 特定的扩展;它们只是为底层方法提供语法糖。没有其他语言 由于接口(interface)中的方法根据定义是公共(public)的,因此它们不被属性封装。您不会通过显示属性由方法支持来透露任何实现细节,因为在接口(interface)中,属性始终由方法支持,而方法始终是公共(public)的。如果封装从一开始就不存在,就不能违反封装。

您的示例具体类具有误导性。首先,那里定义的属性与接口(interface)中定义的属性完全没有联系。您可以将其定义为只读,使其直接访问数据成员,将其设为私有(private),或以任何其他方式与接口(interface)版本不同,包括完全删除它,并且它不会对接口(interface)的用户产生任何影响,进一步借用相信接口(interface)中重要的是方法,而不是属性。编译器会将接口(interface)属性的任何使用直接转换为相应接口(interface)方法之一的使用,这些方法已经是公共(public)的。从未就此事咨询实现对象。

其次,类的可见性说明符是不相关的。无需将方法设为私有(private),因为它们已经在接口(interface)上公开。然而,将它们设为私有(private)并不是一个坏主意,因为它鼓励通过接口(interface)正确使用该类。

您可能会提示接口(interface)的访问器方法应该能够是私有(private)的,但这与一般要求接口(interface)方法能够私有(private)是一样的,这是没有意义的。显然无法调用的方法不是接口(interface)的一部分。回想一下,任何支持 COM 的语言都可以使用接口(interface),甚至是没有属性概念的语言,例如 C 和 C++。这些语言也需要能够调用访问器方法。如果这些方法在某种程度上是私有(private)的,则该接口(interface)将无法在这些语言中工作。

<小时/>

当 Delphi 类的属性引用字段时,该详细信息实际上是该类面向公众的接口(interface)的一部分。任何使用该属性的代码都知道该属性只是字段的别名(即使代码的作者不知道这一点)。如果更改属性定义,则需要重新编译使用该类的任何代码,以便编译器可以生成用于访问该属性的新代码。

当属性需要由方法支持时,您实际上无法再更改属性定义。只有实现可以更改,因此接口(interface)的使用者不需要仅仅因为您选择按需计算属性而不是从存储的字段中读取属性而重新编译。

关于delphi - 它是否违反了接口(interface)属性访问器公开的封装?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10852909/

相关文章:

delphi - 在 Delphi 中创建表单编辑器

java - 控制 Java 断言 - 最佳实践

oop - 策略设计模式的确切定义是什么?

java - 在父类之间来回转换后,子对象是否会丢失其独特的属性

java - 如何将 Properties 对象从一个 Intent 传递到另一个 Intent ?

javascript - 检查 JavaScript 中深层嵌套对象属性是否存在的最简单方法是什么?

c# - Delphi 和可空类型

delphi - MakeScreenshot 泄露?

当 header 中没有返回字符集时,REST 请求内存泄漏

c# - OOP——C# 中的消息传递