我们可以说:
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
答案 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
)的属性。但无论您如何实现属性的read
和write
(如果有的话),从类用户的角度来看,该属性看起来都是一样的。他不必记得使用SetSweaterColor
或GetSweaterColor
(事实上,他们是私人的,他无法访问),但只有SweaterColor
属性。
这也暗示了使用属性的另一个好处。公共和已发布的属性对类的用户可见,而私有成员则不可见(如字段FSweaterColor
和SetSweaterColor
过程)。这很好。因为现在您知道类用户更改人物毛衣颜色的唯一方法是使用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类。您可以在对象检查器中更改的所有内容(Caption
,Width
,Name
等)都会在源代码中使用property
关键字进行标记。
如果您创建的课程将在您的计划中使用,但不会用作,则不要使用property
关键字。