属性和功能或程序之间的差异

时间:2013-02-16 11:58:54

标签: delphi

我们可以说:

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...}

...

请向我解释我们需要使用“财产”的地方,而不是。 TNX

3 个答案:

答案 0 :(得分:13)

这是关于班级的设计的全部内容。从技术上讲,你可以用属性做“一切”,你可以在没有的情况下做,但代码不会那么优雅。良好的设计也使课程更容易使用,并降低了犯错的风险。

首先,你的比较

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字段和公共GetSweaterColor以及SetSweaterColor也可以,但是您需要编写一个即使无需处理来获取颜色,GetSweaterColor也会起作用。此外,该类的用户需要学习使用两个标识符而不是一个。

更具体地说,如果使用Delphi IDE进行编程,您将看到published property(-y + ies)将出现在Object Inspector中,您可以在其中读取/更改它们(如果适用)。如果它不属于属性,那怎么可能呢?

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

所以,毕竟,你需要在逐个班级的基础上决定你班级的优秀设计。我想我的过长答案的简短版本类似于David的评论:

  

使用您喜欢的任何一个,以较方便为准。

答案 1 :(得分:1)

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

此外,他们从处理数据的方法中分离出“变量似的”东西(因此数据,对象应该使用)。

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

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

答案 2 :(得分:0)

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

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

如果您创建的课程将在您的计划中使用,但不会用作,则不要使用property关键字。