使用getter和setter(只获取和设置)而不是简单地为这些变量使用公共字段有什么好处?

如果getter和setter所做的不仅仅是简单的get/set,我可以很快地解决这个问题,但我不是100%清楚如何做到:

public String foo;

比:

private String foo;
public void setFoo(String foo) { this.foo = foo; }
public String getFoo() { return foo; }

而前者需要的样板代码要少得多。


当前回答

getter/setter的一个相对现代的优点是,它使在标记(索引)代码编辑器中浏览代码变得更容易。例如,如果您想查看谁设置了成员,可以打开setter的调用层次结构。

另一方面,如果成员是公共的,则这些工具无法过滤对该成员的读/写访问。因此,您必须费力地使用该成员。

其他回答

取决于你的语言。您已经将其标记为“面向对象”而不是“Java”,因此我想指出ChssPly76的答案依赖于语言。例如,在Python中,没有理由使用getter和setter。如果需要更改行为,可以使用一个属性,该属性将getter和setter包装在基本属性访问周围。类似于:

 class Simple(object):
   def _get_value(self):
       return self._value -1

   def _set_value(self, new_value):
       self._value = new_value + 1

   def _del_value(self):
       self.old_values.append(self._value)
       del self._value

   value = property(_get_value, _set_value, _del_value)

谢谢,这真的澄清了我的想法。现在有10个(几乎)不使用getter和setter的好理由:

当您意识到您需要做的不仅仅是设置和获取值时,您可以将字段设为私有,这会立即告诉您直接访问它的位置。在那里执行的任何验证都只能是上下文无关的,而实际上很少进行这种验证。您可以更改设置的值-当调用者传递给您一个他们(震惊恐惧)希望您按原样存储的值时,这绝对是一场噩梦。你可以隐藏内部表示-太棒了,所以你要确保所有这些操作都是对称的,对吗?你已经将你的公共界面与表单下的更改隔离开来——如果你在设计一个界面,但不确定直接访问某个东西是否可行,那么你应该继续设计。一些库期望这样做,但并不多——反射、序列化、模拟对象都能很好地处理公共字段。通过继承这个类,您可以覆盖默认功能——换句话说,您不仅可以隐藏实现,而且可以使其不一致,从而真正混淆调用者。

最后三个我要离开(N/A或D/C)。。。

在不支持“财产”(C++、Java)或在将字段更改为财产(C#)时需要重新编译客户端的语言中,使用get/set方法更容易修改。例如,向setFoo方法添加验证逻辑不需要更改类的公共接口。

在支持“真实”财产的语言中(Python、Ruby或Smalltalk?),没有必要使用get/set方法。

我只是想补充一点,即使有时它们对于变量/对象的封装和安全是必要的,如果我们想编写一个真正的面向对象的程序,那么我们需要停止过度使用附件,因为有时我们在不真正必要的情况下非常依赖它们,这几乎与我们将变量公开一样。

因为从现在起2周(月、年),当您意识到setter需要做的不仅仅是设置值时,您还将意识到该属性已直接用于238个其他类:-)