在我看过的代码中,有些人经常使用私有变量,例如
private static int number;
他们通常有访问方法,如
public static int returnNumber(){
return number;
}
但我的问题是,重点是什么?我的方式就是这个
int number;
当我需要访问它时,请执行此操作
int numberToBeAssigned = someClass.number;
而不是
int numberToBeAssigned = someClass.getNumber();
对我来说,使用访问器方法和私有变量似乎是不切实际的,我知道他们做了什么,私有变量只允许被它们所在的类访问。我只是没有看到它们的必要性,当你可以轻松地实例化类并在需要时调用它的成员变量。我的逻辑显然是错的,但我希望有人能够提供一个关于私有变量和访问器方法如何被利用的明确例子。
谢谢
答案 0 :(得分:6)
这样的访问器的重点是允许您重新设计实现而不会破坏所有其他代码。例如,如果您稍后决定number
应该来自文件,该怎么办?或者应该转移到另一个班级?
如果您有权访问访问者,那么您可以进行类似的更改,您只需要更改访问者 - 您不必更改依赖于它的所有其他代码。
答案 1 :(得分:2)
这完全是关于封装。公共领域让任何一个类都出现并改变你的价值观,并可能打破你的不变量。如果你只有一个public int foo
,任何人都可以设置它。如果它是private int foo
并且你提供了一个吸气剂,人们只能得到它。如果你提供一个getter和setter,那么他们可以同时执行这两个操作,但是你仍然可以控制它;你可以拒绝一个会破坏班级必须(或想要)做出假设的改变。
可能你现在没有在这个班级中有任何这样的假设,但是a)你将来可能会有一些假设b)其他班级确实有这些假设,因此需要保护他们的私人领域,拥有一致的访问数据的方式很不错(在某些情况下不是字段,在其他情况下是getter和setter)。
实际上,这是关于基本的OO原则:你的类不仅仅是一个状态的blob,它是一个某种东西,它具有属性和动作 - 并且在引擎盖下有状态来反映那些动作。例如,当您要求List
的{{1}}时,您在概念上并不关心是否将其报告为缓存值,或者length()
是否对其元素进行了迭代并计算他们;你只想要它的长度。
这将我们带到最后一个重点(至少在这个答案:)),这是一个getter和setter可以被覆盖以利用继承,而一个字段不能。
答案 2 :(得分:0)
以下是wikipedia的观点:
隐藏对象的内部通过阻止用户将组件的内部数据设置为无效或不一致状态来保护其完整性。封装的一个好处是它可以通过允许开发人员限制软件组件之间的相互依赖性来降低系统复杂性,从而提高稳健性。
答案 3 :(得分:0)
有很多关于这些问题的书籍,答案无法用stackoverflow答案格式完全解释。实际上,这非常重要。简而言之,您在代码中提供的评估者越少,您在重构时就有更多机会进行更改,而不会损坏使用它的人的代码。您的代码变得干净而且健壮,您可以获得更好的不变性,您可以做出更好的架构决策。
答案 4 :(得分:0)
简短回答: 您希望通过尽可能少地发布组件来尽量减少不需要的交互,从而尽可能地保持组件的行为,并尽可能地在应用程序中执行,因为它的行为是孤立的(可以轻松地进行测试)
更长的回答: 类型的方法表示其合约,而其变量表示其状态。任何非平凡类型都将包含多个成员变量,这些变量具有自己的相互关联状态。随着该类型(其合同)提供的功能(新的或扩展的功能,错误修复)的发展,程序员必须牢记所有这些关系,以确保现有行为不会被破坏。
一种经过验证的方法是编写单元测试,但这些只能单独验证类型。通过最小化对类型状态的阐述并将其限制为易于理解和计划的操作,程序员试图最小化他或她能够测试的模型的中断。
相反,如果外部组件有办法访问组件状态超出该类型设计者计划的组件状态,那么它们很容易无意中破坏其行为。组件之间的交互是指数级的:根据我的经验,一旦一个程序理解了超过20,000行代码,由多个开发人员创作,每个开发人员都专注于单独的模块,并经过多次修订,没有人会对整体有一个完美的想法代码了。
关于这个主题已经写了很多书籍和文章,我相信它们会比我更有说服力和说服力。对于Java中的一般最佳实践,我强烈推荐Josh Bloch的Effective Java(第2版)。