我想我一直在互换/错误地使用这些术语!
10 回答
Iain,这基本上是一个术语问题,尽管与此问题相关的“语言不可知”标签,但与语言/环境非常相关。
为了设计讨论,属性和实例变量可以互换使用,因为这个想法是属性是描述对象的数据项。
在谈论特定语言时,这两者可能会有所不同。例如,在 C# 中,属性实际上是返回对象的函数,而实例变量是类的非静态成员变量。
Hershi 认为这是特定于语言的,这是正确的。但要添加到语言特定答案的线索:
在python中,实例变量是实例的属性,(通常)在实例的字典中引用的东西。这类似于 Java 中的成员或实例变量,除了一切都是公共的。
属性是 getter/setter 方法的快捷方式,看起来就像一个实例变量。因此,在以下类定义中(根据 Guido 的新样式对象 manifesto修改):
class C(object):
def __init__(self):
self.y = 0
def getx(self):
if self.y < 0: return 0
else: return self.y
def setx(self, x):
self.y = x
x = property(getx, setx)
>>> z = C()
>>> z.x = -3
>>> print z.x
0
>>> print z.y
-3
>>> z.x = 5
>>> print z.x
5
>>> print z.y
5
y
是 的实例变量z
,x
是属性。(通常,在定义属性的地方,有一些技术用于隐藏关联的实例变量,以便其他代码不会直接访问它。)python 中属性的好处是设计者不必四处走动抢先封装所有实例变量,因为将来通过将实例变量转换为属性的封装不应破坏任何现有代码(除非代码利用您的封装试图修复的漏洞,或依赖类检查或其他一些元数据-编程技术)。
所有这些都是一个很长的答案,说在设计层面,谈论属性是件好事。您可能需要执行哪种类型的封装是不可知的。我想这个原则与语言无关,但确实适用于 python 之外的语言。
在目标 c 中,属性是一个实例变量,它可以利用重载的点运算符来调用它的 setter 和 getter。所以 my.food = "cheeseburger" 实际上被解释为 [my setFood:"cheeseburger"]。这是另一种定义绝对与语言无关的情况,因为objective-c 定义了@property 关键字。
用 C# 完成的代码示例
public class ClassName
{
private string variable;
public string property
{
get{ return variable; }
set { variable = value; }
}
}
也许那是因为你最初来自 C++ 对吧?!在我的学生时代,我有教授一直在说班级属性或班级属性。自从我进入 Java C# 世界以来,我开始听到有关成员的消息。类成员、实例成员...
然后属性出现!在 Java 和 .NET 中。所以我认为你最好称它为成员。无论它们是实例成员(或者你称之为实例变量)还是类成员......
干杯!
一个属性可以,我想大多数情况下,返回一个实例变量,但它可以做更多的事情。您可以将逻辑放在属性中,聚合值或更新其他实例变量等。我认为最好避免这样做。逻辑应该进入方法。
在 Java 中,我们有一个叫做JavaBeans Properties的东西,但这基本上是一个实例变量,它的 getter 和 setter 遵循一定的命名模式。
另外,在像 C# 这样的语言中,属性本质上是一个 get 和 set 函数。因此,除了获取/设置之外,它还可以具有运行的自定义逻辑。实例变量无法做到这一点。
属性是与对象关联的某种数据。例如,圆的一个属性是它的直径,另一个是它的面积。
实例变量是存储在对象中的一段数据。它不一定需要直接与属性对应。例如(呵呵),圆可以将其半径存储在实例变量中,并根据该半径计算其直径和面积。这三个仍然是属性,但只有半径存储在实例变量中。
某些语言具有“一流”属性的概念。这意味着对于客户端应用程序,该属性看起来和使用起来就像一个实例变量。也就是说,不是写类似的东西,而是circle.getDiameter()
写circle.diameter
,而不是写,而不是circle.setRadius(5)
写circle.radius = 5
。
与给出的其他答案相比,我确实认为成员变量和与语言无关的属性之间存在有用的区别。
这种区别在面向组件的编程中最为明显,它在任何地方都很有用,但在图形 UI 中最容易理解。在这种情况下,我倾向于将组件的设计时配置视为操纵对象的“属性”。例如,我通过设置文本输入字段的属性来选择文本输入字段的前景色和背景色、边框样式和字体。虽然这些属性可以在运行时更改,但通常不会。在运行时,代表字段内容的一组不同的变量更有可能被读取和写入。我将此信息视为组件的“状态”。
为什么这种区分有用?在创建将组件连接在一起的抽象时,通常只需要公开“状态”变量。回到文本字段示例,您可以声明一个提供对当前内容的访问的接口。但是控制组件外观和感觉的“属性”只定义在具体的实现类上。