【问题标题】:Difference between property and function or procedures属性与功能或过程之间的区别
【发布时间】:2013-02-16 11:58:53
【问题描述】:

我们可以说:

type
  TPerson = class
   private
     pName : string;
   public
     property Name : string read pName write pName;
end;

等于:

 type
  TPerson = class
   private
     pName : string;
   public
     procedure SetName(val: string);
     function GetName:String;
end;

//{... implementing SetName And GetName...}

??

请向我解释我们需要在哪些地方使用“属性”,哪些地方不需要。天呐

【问题讨论】:

  • 在 Delphi 中,习惯上使用F 作为(私有)字段的前缀,即FName
  • 随心所欲使用,哪个更方便。
  • 我个人不会将p 用于私有字段,因为P 已经被广泛用作指针类型,例如PCharF 是最常用的。

标签: delphi


【解决方案1】:

这完全是关于班级的设计。从技术上讲,你可以用 属性做的“所有事情”,你也可以用 不用 属性做,但是代码不会那么优雅。良好的设计还使类更易于使用,并降低出错的风险。

首先,你的比较

TPerson = class
  private
    FName: string;
  public
    property Name: string read FName write FName;
  end;

TPerson = class
  private
    FName: string;
  public
    procedure SetName(const Name: string);
    function GetName: string;
  end;

不太公平。事实上,在第一种情况下,当值被设置(或读取)时,您没有机会做某事。所以更合适的比较是将后面的代码与

TPerson = class
  private
    FName: string;
    procedure SetName(const Name: string);
    function GetName: string;
  public
    property Name: string read GetName write SetName;
  end;

例如,如果您编写一个控件,您通常需要在更改属性时使控件无效(基本上是重新绘制),例如TPerson 的“毛衣颜色”。例如,

TPerson = class
  private
    FSweaterColor: string;
    procedure SetSweaterColor(const Value: TColor);
  public
    property SweaterColor: TColor read FSweaterColor write SetSweaterColor;
  end;

  ...

  implementation

  procedure TPerson.SetSweaterColor(const Value: TColor);
  begin
    if FSweaterColor <> Value then
    begin
      FSweaterColor := Value;
      Invalidate; // causes a repaint of the control
    end;
  end;

无论如何,属性的意义何在?嗯,基本上,重点是为该类创建一个漂亮的接口:对于对其实现细节不感兴趣的人来说,它应该易于使用。通过使用属性,您可以实现此目标。实际上,要读取毛衣的当前颜色,您只需读取Anna.SweaterColor,要设置它,您只需Anna.SweaterColor := clRed。您不知道这是否只是设置变量或导致过程运行,您不在乎。就您而言,TPerson 对象只具有一个名为 SweaterColor 的可读且可设置的属性。

您还可以创建只读(无write)或只写(无read)的属性。但是无论您如何实现属性的readwrite(如果有的话),从类用户的角度来看,该属性看起来都是一样的。他不必记得使用SetSweaterColorGetSweaterColor(事实上,它们是私有的,他无法访问),而只需要使用SweaterColor 属性。

这也暗示了使用属性的另一个好处。公共和发布的属性对类的用户可见,而私有成员不可见(如字段FSweaterColorSetSweaterColor 过程)。这很好。因为现在您知道类用户更改人的毛衣颜色的唯一方法是使用SweaterColor 属性,它保证会重新绘制控件。如果FSweaterColor 变量是公开的,该类的用户可能会设置它并想知道,“为什么当我更改毛衣颜色时没有任何反应?”当然,您不需要属性来获得此好处:私有 FSweaterColor 字段和公共 GetSweaterColorSetSweaterColor 也可以,但是即使如此,您也需要编写 GetSweaterColor 函数无需处理即可获得颜色。此外,该类的用户需要学习使用两个标识符而不是一个。

更具体地说,如果您使用 Delphi IDE 进行编程,您将看到 published property (-y+ies) 将显示在 Object Inspector 中,您可以在其中读取/更改它们(如果适用) .如果没有房产,这怎么可能?

话虽这么说,有时你不使用属性,即使你可以。例如,如果您有一个只读“属性”,您可能会选择一个公共 GetSomething 函数而不是只读属性。毕竟,这将为您节省一些编码。同样,如果您有一个只写属性,您可以使用单个公共SetSomething 过程,这也将节省您的代码。最后,如果你有一个读/写属性不需要任何处理(既不需要获取也不需要设置),你可以简单地使用公共变量!

所以,毕竟,您需要逐个班级决定一个好的班级设计。我想我过长的答案的简短版本类似于大卫的评论:

使用您喜欢的任何一个,哪个更方便。

【讨论】:

  • 这太片面了。 Anna.SweaterColor := clRed 和 Anna.SetSweaterColor(clRed) 之间并没有太大区别。只是语法不同。如果你习惯了后者,那读起来就好了。没有问题使用它。唯一显着的区别是能够在属性读取器中返回字段,而不必编写 getter 函数。以及对 OI 属性的需求。而且我敢肯定它们是为 OI 服务而发明的。
  • @David:我知道。事实上,在过去的 10 分钟里,我在打扫公寓时一直在考虑这个问题。我再补充一点。
  • C++ 程序员会说,为什么要发明一种语言特性来做我们已经可以做的事情。我个人觉得属性是可读的,但有多少是内在的,有多少是习得的行为?
【解决方案2】:

属性是一个很好的语法糖。它们相当于一对 getEnabled 和 setEnabled 方法,但大多数程序员(和编程语言)更喜欢属性。例如,代码完成窗口中的条目较少。

此外,它们将“类似变量”的东西(因此数据,对象应该使用)与使用数据的方法分开。

属性不仅限于组件,否则它们非常有用。您可以定义一个带有属性的公共接口,然后实现一些验证逻辑。 (不能使用公共字段)但是对于一个简单的属性,您只需要两行代码,而方法是 8 行。

对于对象检查器来说更重要的是发布的关键字,只有发布的属性会显示在 OI 中。

【讨论】:

  • 此外,它们将“类似变量”的东西(因此数据,对象应该使用)与使用数据的方法分开。 getter/setter 也是如此方法。
  • 但它们仍然是方法。在代码完成中有方法图标。可以用作回调函数。而且它们在代码完成中聚集在一起(按字母顺序排列),我看不出它是只读的还是读/写的。
【解决方案3】:

没有。这两个代码不相等。

当我们将TPerson 类作为组件实现时,我们使用property,可以在Delphi 的对象检查器中自定义。例如,看一下 TButton 类。您可以在 Object Inspector 中更改的所有内容(CaptionWidthName 等)在源代码中都使用 property 关键字进行标记。

如果您创建一个将在您的程序中使用的类而不是作为组件,则不要使用property 关键字。

【讨论】:

  • property 是对象的属性,您可以在其中关联读取和写入其数据的操作。仅在TComponents 中使用没有限制。相反,它对于隐藏类的实现细节非常有用。
  • 但是为什么我们不在简单的类(无组件)中使用“属性”?因为它做了我们需要做的事情......
  • @Hamed:这是关于班级的设计。从技术上讲,你可以用属性做任何事情,你也可以不用它们,但是在很多情况下代码会不太优雅。
  • Bogdan:你最后一段完全是错误的。诚然,已发布的属性会显示在 Object Inspector 中,但这只是额外的好处。毕竟,Delphi 编程语言可以在记事本中使用,您仍然可以使用属性。
  • 但我不得不承认,Object Inspector 的“奖励”不仅是我最初猜测的奖励,而且可能是引入 property 关键字的一大动力。
猜你喜欢
  • 2011-08-26
  • 2012-11-04
  • 2015-04-26
  • 1970-01-01
  • 2010-12-07
  • 2013-10-12
  • 2012-10-03
  • 2011-06-22
  • 2012-08-27
相关资源
最近更新 更多