Java OOP公共vs私有vs受保护
我了解公共、私人和受保护的机构的工作。我知道您应该使用它们来遵守面向对象编程的概念,并且我知道如何在使用多个类的程序中实现它们 我的问题是:我们为什么要这样做?为什么我不应该让一个类直接修改另一个类的全局变量?即使不应该,为什么还要使用受保护、私有和公共修饰符?这就好像程序员不相信自己不会这么做,即使他们是编写程序的人Java OOP公共vs私有vs受保护,java,oop,class,variables,methods,Java,Oop,Class,Variables,Methods,我了解公共、私人和受保护的机构的工作。我知道您应该使用它们来遵守面向对象编程的概念,并且我知道如何在使用多个类的程序中实现它们 我的问题是:我们为什么要这样做?为什么我不应该让一个类直接修改另一个类的全局变量?即使不应该,为什么还要使用受保护、私有和公共修饰符?这就好像程序员不相信自己不会这么做,即使他们是编写程序的人 提前感谢。请记住,编写给定类的开发人员可能不是唯一使用它的人。开发团队编写软件库,Java中的软件库通常作为JAR分发,由完全不同的开发团队使用。如果没有这些标准,其他人至少很难
提前感谢。请记住,编写给定类的开发人员可能不是唯一使用它的人。开发团队编写软件库,Java中的软件库通常作为JAR分发,由完全不同的开发团队使用。如果没有这些标准,其他人至少很难知道任何可用变量/方法的意图是什么 例如,如果我有一个私有/受保护的实例变量,我可能会有一个公共的“setter”方法来检查有效性、前提条件,并执行其他活动——如果任何人能够自由地直接修改实例变量,所有这些都将被绕过 Java文档/教程中的另一个要点是: 公共字段倾向于将您链接到特定的实现和 限制更改代码的灵活性
你说得对,那是因为我们不能相信自己。可变状态是计算机程序复杂性的一个主要因素,它太容易构建一个起初看起来正常,后来随着系统变大而失控的东西。限制访问有助于减少对象状态以不可预知的方式发生变化的机会。其思想是让对象通过定义良好的通道彼此通信,而不是直接调整彼此的数据。这样,我们就有希望测试单个对象,并对它们作为更大系统的一部分的行为有信心。
- 非本地行为很难推理李>
- 减少表面积可以提高理解力
- 我不相信自己能记住所有的行为副作用
- 我绝对不相信“你”能理解所有的行为副作用
- 我暴露的越少,修改和扩展的灵活性就越大
如果我写一个类并声明一个方法或字段<代码>私下<代码>,我知道我不必考虑如果其他类调用/访问/修改它会发生什么问题。如果我正在阅读别人的代码,我知道在映射交互和边界时,我可以(最初)忽略
private
部分。私有
和受保护的
修饰符和包私有
提供不同粒度的边界
(或者可能是关于信任;也就是说,不相信自己记住我们设计中的抽象边界在哪里。)让我给出一个基本示例(这只是为了说明): 一切看起来都很好,你很开心。现在,您意识到其他开发人员或您用来设置值的其他API正在设置为
0
,这导致Bar.process()函数出现异常
现在,根据上述实现,您无法限制用户将其设置为0。现在看看下面的实现
class Foo {
void processBar() {
Bar bar = new Bar();
bar.setValue(0);
bar.process();
}
}
class Bar {
public int value;
public void setValue(int value) {
if(value == 0)
throw new IllegalArgumentException("value = 0 is not allowed");
this.value = value;
}
public void process() {
// Say some code
int compute = 10/value;
// No need to write exception handling code
// so in theory can give u better performance too
}
}
现在,您不仅可以进行检查,还可以给出一个信息丰富的异常,这有助于在早期快速发现错误
这只是其中一个例子,OOP的基础知识(封装、抽象等)可以帮助您标准化接口并隐藏底层实现 基本上有两个原因:
1) Java中存在需要安全性的接口。例如,在您的机器上运行java小程序时,您希望确保小程序不能访问未经授权的文件系统的某些部分。如果没有可强制执行的安全性,小程序可以进入Java安全性
class Foo {
void processBar() {
Bar bar = new Bar();
bar.setValue(0);
bar.process();
}
}
class Bar {
public int value;
public void setValue(int value) {
if(value == 0)
throw new IllegalArgumentException("value = 0 is not allowed");
this.value = value;
}
public void process() {
// Say some code
int compute = 10/value;
// No need to write exception handling code
// so in theory can give u better performance too
}
}