我想我一直在互相错误地使用这些术语!
答案 0 :(得分:17)
Iain,这基本上是一个术语问题,尽管与这个问题相关的“语言无关”标签,但语言/环境非常相关。
为了设计讨论,属性和实例变量可以互换使用,因为这个想法是属性是描述对象的数据项。
在谈论特定语言时,这两种语言可能不同。例如,在C#中,属性实际上是返回对象的函数,而实例变量是类的非静态成员变量。
答案 1 :(得分:3)
Hershi说这是特定于语言的。但要添加语言特定答案的痕迹:
在python中,实例变量是实例的属性,(通常)是实例字典中引用的东西。这类似于Java中的成员或实例变量,除了一切都是公共的。
属性是getter / setter方法的快捷方式,看起来就像一个实例变量。因此,在以下类定义中(从Guido的new style object 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旁边的语言。
答案 2 :(得分:2)
在C#中完成的代码示例
public class ClassName
{
private string variable;
public string property
{
get{ return variable; }
set { variable = value; }
}
}
答案 3 :(得分:2)
在目标c中,属性是一个实例变量,它可以利用重载点运算符来调用其setter和getter。所以my.food =“cheeseburger”实际上被解释为[我的setFood:“cheeseburger”]。这是另一种情况,其定义绝对不是语言不可知的,因为objective-c定义了@property关键字。
答案 4 :(得分:1)
也许那是因为你第一次来自C ++吧?! 在我上学的日子里,我有教授说课堂属性或课程一直都是属性的。自从我搬到Java C#世界以来,我开始听到会员的意见。类成员,实例成员......
然后属性apear!在Java和.NET中。所以我认为你称之为会员更好。他们是实例成员(或称为实例变量)或类成员....
干杯!
答案 5 :(得分:1)
一个属性可以,而且我想大多数情况下会返回一个实例变量,但它可以做更多。您可以将逻辑放在属性中,聚合值或更新其他实例变量等。但我认为最好避免这样做。逻辑应该进入方法。
答案 6 :(得分:0)
在Java中,我们有一些名为JavaBeans Properties的东西,但它基本上是一个实例变量,它遵循其getter和setter的某个命名模式。
答案 7 :(得分:0)
除了已经说过的内容之外,在像C#这样的语言中,属性本质上是一个get和set函数。因此,它可以具有除获取/设置之外运行的自定义逻辑。实例变量不能这样做。
答案 8 :(得分:0)
属性是与对象关联的某种数据。例如,圆的属性是它的直径,另一个是它的面积。
实例变量是存储在对象中的一段数据。它不一定需要直接与属性对应。例如(heh),圆可以将其半径存储在实例变量中,并基于该半径计算其直径和面积。这三个仍然是属性,但只有半径存储在实例变量中。
有些语言具有“第一类”属性的概念。这意味着对于客户端应用程序,该属性看起来像实例变量一样使用。也就是说,不是写circle.getDiameter()
之类的内容,而是写circle.diameter
,而不是circle.setRadius(5)
,而是写circle.radius = 5
。
答案 9 :(得分:0)
与给出的其他答案相反,我做认为成员变量和与语言无关的属性之间存在有用的区别。
这种区别在面向组件的编程中最为明显,它在任何地方都很有用,但在图形用户界面中最容易理解。在这种情况下,我倾向于将组件的设计时配置视为操纵对象的“属性”。例如,我通过设置其属性来选择文本输入字段的前景色和背景色,边框样式和字体。虽然这些属性可以在运行时更改,但它们通常不会。在运行时,表示字段内容的不同变量集更有可能被读取和写入。我认为这些信息是组件的“状态”。
为什么这种区别有用?在创建将组件连接在一起的抽象时,通常只需要暴露“状态”变量。回到文本字段示例,您可以声明一个提供对当前内容的访问的接口。但是控制组件外观的“属性”仅在具体的实现类上定义。