LAT*_*LAT 20 java oop visibility
我是编程新手.我现在正在学习Java,有些东西我不太确定,那就是使用私有.为什么程序员将变量设置为私有,然后将write,getter和setter设置为访问它.无论如何,为什么不把所有东西都公之于众.
public class BadOO {
public int size;
public int weight;
...
}
public class ExploitBadOO {
public static void main (String [] args) {
BadOO b = new BadOO();
b.size = -5; // Legal but bad!!
}
}
Run Code Online (Sandbox Code Playgroud)
我发现了一些像这样的代码,我看到评论合法但很糟糕.我不明白为什么,请解释一下.
Mar*_*tin 22
最重要的原因是隐藏类的内部实现细节.如果您阻止程序员依赖这些细节,您可以安全地修改实现,而不必担心您将破坏使用该类的现有代码.
因此,通过将字段声明为私有,可以防止用户直接访问该变量.通过提供gettters和setter,您可以精确控制用户如何控制变量.
Edw*_*uck 17
不仅仅是将变量公之于众的主要原因是,如果你确实公开它,你会在以后创建更多的麻烦.
例如,一个程序员围绕私有成员变量编写公共getter和setter.三个月后,他需要验证变量永远不会"设置"为null.他在"setFoo(...)"方法中添加了一个检查,然后检查所有设置变量的尝试是否"将其设置为null".案件结束,并且很费力.
另一个程序员意识到,围绕私有成员变量放入公共getter和setter是违反封装精神的,他认为方法是徒劳的,并且决定公开成员变量.也许这会获得一点性能提升,或者程序员可能只是想"按照它的使用来编写它".三个月后,他需要验证变量永远不会"设置"为null.他扫描对变量的每次访问,有效地搜索整个代码库,包括可能通过反射访问变量的所有代码.这包括已扩展其代码的所有第三方库,以及在编写后使用其代码的所有新编写的模块.然后,他修改所有调用以保证变量永远不会设置为null.案件永远不会关闭,因为他无法有效地找到对公开成员的所有访问,也无法访问所有第三方源代码.由于对新编写的模块缺乏了解,调查保证不完整.最后,他无法控制可能访问公共成员的未来代码,并且该代码可能包含将成员变量设置为null的行.
当然,第二个程序员可以通过在变量周围放置"get"和"set"方法并将其设置为私有来破坏所有现有代码,但是,嘿,他可以在三个月前完成这个并保存自己解释为什么他需要打破其他人的代码.
把它称之为你想要的,但是将公共"获取"和"设置"方法放在私有成员变量周围的是防御性编程,这是多年(即数十年)经验带来的.
你班上公开的任何东西都是与班级用户签订的合同.在修改类时,必须维护合同.您可以添加到合同(新方法,变量等),但不能从中删除.理想的是,您希望合同尽可能小.让一切都变得私密是很有用的.如果您需要从包成员直接访问,请将其保护.只将这些内容公之于众.
公开变量意味着您将永远签约,拥有该变量并允许用户修改它.如上所述,您可能会发现在访问变量时需要调用行为.如果您只收缩getter和setter方法,则可以执行此操作.
许多早期的Java类都有合同要求它们是线程安全的.在只有一个线程可以访问实例的情况下,这会增加大量开销.较新的版本具有复制或增强功能但删除同步的新类.因此添加了StringBuilder,在大多数情况下应该使用StringBuilder而不是StringBuffer.