Java OOP公共vs私有vs受保护

Java OOP公共vs私有vs受保护,java,oop,class,variables,methods,Java,Oop,Class,Variables,Methods,我了解公共、私人和受保护的机构的工作。我知道您应该使用它们来遵守面向对象编程的概念,并且我知道如何在使用多个类的程序中实现它们 我的问题是:我们为什么要这样做?为什么我不应该让一个类直接修改另一个类的全局变量?即使不应该,为什么还要使用受保护、私有和公共修饰符?这就好像程序员不相信自己不会这么做,即使他们是编写程序的人 提前感谢。请记住,编写给定类的开发人员可能不是唯一使用它的人。开发团队编写软件库,Java中的软件库通常作为JAR分发,由完全不同的开发团队使用。如果没有这些标准,其他人至少很难

我了解公共、私人和受保护的机构的工作。我知道您应该使用它们来遵守面向对象编程的概念,并且我知道如何在使用多个类的程序中实现它们

我的问题是:我们为什么要这样做?为什么我不应该让一个类直接修改另一个类的全局变量?即使不应该,为什么还要使用受保护、私有和公共修饰符?这就好像程序员不相信自己不会这么做,即使他们是编写程序的人


提前感谢。

请记住,编写给定类的开发人员可能不是唯一使用它的人。开发团队编写软件库,Java中的软件库通常作为JAR分发,由完全不同的开发团队使用。如果没有这些标准,其他人至少很难知道任何可用变量/方法的意图是什么

例如,如果我有一个私有/受保护的实例变量,我可能会有一个公共的“setter”方法来检查有效性、前提条件,并执行其他活动——如果任何人能够自由地直接修改实例变量,所有这些都将被绕过

Java文档/教程中的另一个要点是:

公共字段倾向于将您链接到特定的实现和 限制更改代码的灵活性


你说得对,那是因为我们不能相信自己。可变状态是计算机程序复杂性的一个主要因素,它太容易构建一个起初看起来正常,后来随着系统变大而失控的东西。限制访问有助于减少对象状态以不可预知的方式发生变化的机会。其思想是让对象通过定义良好的通道彼此通信,而不是直接调整彼此的数据。这样,我们就有希望测试单个对象,并对它们作为更大系统的一部分的行为有信心。

  • 非本地行为很难推理
  • 减少表面积可以提高理解力
  • 我不相信自己能记住所有的行为副作用
  • 我绝对不相信“你”能理解所有的行为副作用
  • 我暴露的越少,修改和扩展的灵活性就越大
我的问题是:我们为什么要这样做

基本上,因为通过这种方式限制我们自己,我们让事情变得更容易。。。对于我们自己,以及将来可能需要阅读/修改代码的其他人。。。理解代码以及各个部分的交互方式

大多数开发人员通过抽象的思维过程理解代码;i、 e.在思想上围绕代码位绘制边界,孤立地理解每个位,然后理解每个位如何与其他位交互。如果代码的任何部分可能与代码的任何其他部分的“内部”混淆,那么对于典型的开发人员来说,很难理解正在发生的事情

在编写代码时,这对您来说可能不是问题,因为您可以在创建代码时将所有复杂的交互保持在头脑中。但一两年后,你们会忘记很多细节。而其他人从一开始就不知道细节

为什么我不应该让一个类直接修改另一个类的全局变量

因为它使你的代码更难理解;见上文。代码库越大,问题就越明显

另一点是,如果您过度使用全局变量(实际上是静态变量),那么如果您的代码需要多线程/可重入、用于单元测试,或者需要在其他上下文中重用代码,那么您就会产生问题

即使不应该,为什么还要使用受保护、私有和公共修饰符?这就好像程序员不相信自己不会这么做,即使他们是编写程序的人

这与信任无关。它是关于在源代码中表达边界的

如果我写一个类并声明一个方法或字段<代码>私下<代码>,我知道我不必考虑如果其他类调用/访问/修改它会发生什么问题。如果我正在阅读别人的代码,我知道在映射交互和边界时,我可以(最初)忽略

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

  }
}