我了解公共,私人和受保护的行为。我知道您应该使用它们来遵循面向对象编程的概念,并且我知道如何在使用多个类的程序中实现它们。
我的问题是:为什么我们这样做?为什么我不能直接修改另一个类的全局变量?即使你不应该为什么保护,私人和公共修饰符甚至是必要的?这就好像程序员不相信自己不这样做,即使他们是编写程序的人。
提前致谢。
答案 0 :(得分:9)
你是对的,因为我们不能信任自己。可变状态是计算机程序复杂性的一个主要因素,它很容易构建起初看起来不错的东西,随后随着系统变大而变得失控。限制访问有助于减少对象状态以不可预测的方式发生变化的机会。这个想法是让对象通过明确定义的渠道相互通信,而不是直接调整彼此的数据。这样我们就有了测试单个对象的一些希望,并对它们作为更大系统的一部分的行为有了一定的信心。
答案 1 :(得分:6)
让我举一个基本的例子(这只是为了说明):
class Foo {
void processBar() {
Bar bar = new Bar();
bar.value = 10;
bar.process();
}
}
class Bar {
public int value;
public void process() {
// Say some code
int compute = 10/value;
// Her you have to write some code to handle
// exception
}
}
每件事看起来都很好,你很开心。现在,您稍后意识到其他开发人员或您用于设置值的其他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(Encapsulation,Abstraction等)的基础知识,帮助您标准化界面并隐藏底层实现。
答案 2 :(得分:4)
请记住,编写给定类的开发人员可能不是唯一使用它的人。开发人员团队编写软件库,这些库在Java中通常作为JAR分发,由完全不同的开发团队使用。如果没有这些标准,其他人很难至少知道任何可用变量/方法的意图。
例如,如果我有一个私有/受保护的实例变量,我可能有一个公共的“setter”方法来检查有效性,前置条件并执行其他活动 - 如果任何人可以自由修改,那么所有这些都将被绕过实例变量直接。
另一个好处是Java文档/教程:http://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html:
公共字段倾向于将您链接到特定的实现和 限制您更改代码的灵活性。
答案 3 :(得分:2)
答案 4 :(得分:2)
我的问题是:为什么我们这样做?
基本上,因为以这种方式限制自己,我们会让自己和其他可能需要在将来阅读/修改代码的人更容易理解...代码,以及各个部分交互的方式。
大多数开发人员通过抽象的心理过程来理解代码;即精神上在代码位周围绘制边界,单独理解每个位,然后理解每个位如何与其他位交互。如果代码的任何部分可能会混淆代码的任何其他部分的“内部”,那么这使得典型的开发人员很难理解正在发生的事情。
在编写代码时,这对您来说可能不是问题,因为您可以在创建代码时保持头脑中所有复杂的交互。但是在一两年的时间里,你会忘记很多细节。而其他人从来没有从头开始细节。
为什么我不应该让一个类直接修改另一个类的全局变量?
因为它使您的代码更难理解;往上看。代码库越大,问题就越明显。
另一点是,如果您使用过度使用全局变量(实际上是静态),那么如果您的代码需要多线程/可重入,单元测试以及您需要在其他上下文中重用代码,则会产生问题。
即使你不应该为什么保护,私人和公共修饰符甚至是必要的?这就好像程序员不相信自己不这样做,即使他们是编写程序的人。
不是信任。它是关于在源代码中表达边界的地方。
如果我编写一个类并声明一个方法或一个字段private
,我知道我不必考虑如果其他类调用/访问它/修改它会发生什么的问题。如果我正在阅读别人的代码,我知道我可以(最初)在映射交互和边界时忽略private
部分。 private
和protected
修饰符和包私有
提供不同的边界粒度。
(或者也许是关于信任;即不信任我们自己 记住我们设计中的抽象边界在哪里。)
答案 5 :(得分:1)
基本上有两个原因:
1)Java中存在需要安全性的接口。例如,在您的盒子上运行Java小程序时,您希望确保小程序无法访问未经授权的文件系统的某些部分。如果没有强制安全性,applet可以进入Java安全层并修改自己的权限。
2)即使每个人都“信任”,有时权宜之计也胜过常识,程序员绕过API来访问内部接口,而不是增强API(事实上,这通常需要更长的时间)。这会给稳定性和升级兼容性带来问题。
(在古代计算历史的深处,有一个传奇,一个由应用程序员以这种方式处理的操作系统,在某种程度上,维护操作系统的程序员被迫确保某些代码段(不是入口)当操作系统被修改时,点,但实际的内部代码序列)没有改变物理地址。)
请注意,在OOP范例变得普遍之前存在这些问题,并且是OOP的一些动机。 OOP不是一种凭空发明的任意宗教教义,而是一系列已经过大约6年编程经验的原则。