问题描述
我们可以说:
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
Please explain to me where we need to use "property" and where not. Tnx
推荐答案
这全都与该类的设计有关。从技术上讲,您可以通过 属性执行所有操作,也可以在没有 属性的情况下执行操作,但是代码并不那么优雅。良好的设计还可以使类更易于使用,并减少犯错误的风险。
It's all about the design of the class. Technically, 'everything' you can do with properties, you can do without them, but the code will not be as elegant. Good design also makes the classes easier to use, and reduces the risk of making mistakes.
首先,进行比较
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;
不太公平。确实,在第一种情况下,设置(或读取)值后,您就没有机会做某事。因此,更合适的比较是将后一个代码与
isn't quite fair. Indeed, in the first case, you have no chance of doing something when the value is set (or read). So a more appropriate comparison would be to compare the latter code to
TPerson = class
private
FName: string;
procedure SetName(const Name: string);
function GetName: string;
public
property Name: string read GetName write SetName;
end;
例如,如果编写控件,则通常需要使控件无效(基本上是重新绘制)当您更改属性时,例如 TPerson
的毛衣颜色。例如,
For instance, if you write a control, you often need to invalidate (basically, repaint) the control when you alter a property, say, the 'Sweater colour' of the TPerson
. For instance,
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;
无论如何,房产的意义是什么?好吧,基本上,重点是为该类提供一个不错的 interface :对于不关心其实现细节的人,应该易于使用。通过使用属性,可以实现此目标。确实,要读取毛衣的当前颜色,您只需阅读 Anna.SweaterColor
,然后对其进行设置,只需 Anna.SweaterColor:= clRed
。您不知道这是否只是设置了一个变量或导致了一个过程运行,并且您不在乎。就您而言, TPerson
对象只是具有一个可读且可设置的属性,称为 SweaterColor
。
Anyhow, what's the point of properties? Well, the point, basically, is to make a nice interface of the class: It should be easy to use for someone not interested in the details of its implementation. By using properties, you can achieve this goal. Indeed, to read the current colour of the sweater, you just read Anna.SweaterColor
, and to set it, you just Anna.SweaterColor := clRed
. You don't know if this simply sets a variable or causes a procedure to run, and you don't care. As far as you are concerned, a TPerson
object simply has a readable and setable property called SweaterColor
.
您还可以创建只读(无写入
)或只读(无)属性阅读
)。但是,无论您如何实现属性的 read
和 write
(如果有),该属性将看起来像从类用户的角度来看也是一样。他不需要记住使用 SetSweaterColor
或 GetSweaterColor
(实际上,它们是私有的,他不能访问),但是仅 SweaterColor
属性。
You can also create properties that are read-only (no write
) or write-only (no read
). But no matter how you implement the read
and write
(if at all) of a property, the property will look the same from the class user's point of view. He need not remember to use SetSweaterColor
or GetSweaterColor
(in fact, they are private and not accessible to him), but only the SweaterColor
property.
这也暗示了使用属性的另一个好处。该类的用户可以看到公共属性和已发布属性,而私有成员则不可见(例如字段 FSweaterColor
和 SetSweaterColor
过程)。很好因为现在您知道,类用户更改人的毛衣颜色的唯一方法是使用 SweaterColor
属性,该属性将保证重新绘制控件。如果 FSweaterColor
变量是公共的,则该类的用户可能会对此进行设置,并想知道:当我更改毛衣颜色时,为什么什么都没发生?当然,您不需要属性即可获得此好处:私有 FSweaterColor
字段和公共 GetSweaterColor
和 SetSweaterColor
也是一样,但是即使您不需要进行任何处理,也需要编写一个 GetSweaterColor
函数。颜色。另外,该类的用户需要学习使用两个标识符而不是一个。
This also hints at another benefit of using properties. Public and published properties are visible to the users of the class, while the private members are not (like the field FSweaterColor
and the SetSweaterColor
procedure). This is good. Because now you know that the only way for the class user to change the sweater colour of a person is to use the SweaterColor
property, which guaranteed will repaint the control. If the FSweaterColor
variable were public, the user of the class might set this and wonder, "why doesn't anything happen when I change the sweater color?" Of course, you don't need properties to get this benefit: a private FSweaterColor
field and public GetSweaterColor
and SetSweaterColor
would do just as well, but then you'd need to write a GetSweaterColor
function even though no processing is required to get the color. Also, the user of the class need to learn to use two identifiers instead of one.
更具体地说,如果您使用Delphi IDE来程序,您会看到已发布的属性
(-y + ies)将显示在对象检查器中,您可以在其中读取/更改它们(如果适用)。
More concretely, if you use the Delphi IDE to program, you will see that the published property
(-y+ies) will show up in the Object Inspector, where you are allowed to read/change them (if applicable). How would that be possible if it weren't for properties?
所有这些,尽管有时您甚至不使用物业,这怎么可能呢?例如,如果您具有只读的属性,则可以使用单个公共 GetSomething
函数,而不是只读属性。毕竟,这将节省您一些编码。同样,如果您具有只写属性,则可以使用单个公共 SetSomething
过程,该过程也可以节省代码。最后,如果您拥有一个不需要任何处理(获取或设置)的读写属性,则只需使用公共变量即可!
All this being said, sometimes you don't use properties even though you could. For instance, if you have a read-only 'property', you might go for a single public GetSomething
function instead of a read-only property. After all, that would save you some coding. Similarly, if you have a write-only property, you could go with a single public SetSomething
procedure, which will also save you code. Finally, if you have a read/write property that requires no processing either way (neither to get nor to set), you could simply use a public variable!
因此,毕竟,您需要在每个班级的基础上决定班级的良好设计。我猜我的答案过长的简短版本类似于David的评论:
So, after all, you need to decide on a good design of your class on a class-by-class basis. I guess the short version of my overly long answer is similar to David's comment:
这篇关于属性与功能或过程之间的区别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!