【问题标题】:Breaking encapsulation and information hiding in Java打破Java中的封装和信息隐藏
【发布时间】:2017-02-05 01:04:30
【问题描述】:

考虑以下 sn-p。

package breakoop;

public class BreakOOP {

    public static class A{
        private int a;
    }

    public static class B extends A{
        public int f(){
            return super.a;
        }
    }

    public static void main(String[] args) {
        B b = new B();
        System.out.println(b.f());
    }
}

仅当 AB 封装在 BreakOOP 类中时,该示例才会编译。

这似乎违背了 OOP 的一些基本概念。有人可以解释为什么会编译吗?背后的原因是什么?

【问题讨论】:

  • 我猜你指的是super.a。之所以可以编译,是因为规范说明了任何私有成员在顶级类的范围内都是可见的,即在您的情况下在 BreakOOP 内(我将不得不查找 JLS 的相关部分)。跨度>
  • 内部类从其父类获取可见性规则。这是为什么? - 争论不休,这只是它在java中的方式。因此,从 B 访问 super.a 就像 BreakOOP 类中的两个私有变量。如果您想要更广泛的保护,则必须将它们移动到不同的编译单元中。
  • 我不知道为什么允许这样做的原因,但在我看来,它增加了封装性的论点似乎类似于为什么 C++ 中的朋友关键字可以增加封装性的论点。
  • 为什么你认为它不应该编译?

标签: java oop inheritance encapsulation information-hiding


【解决方案1】:

检查这个:https://docs.oracle.com/javase/tutorial/java/javaOO/nested.html。它说它通过允许 static 类访问顶级类的私有成员来增加封装(有时您可能需要这样做)。 a 是类 A 的私有成员,属于 BreakOOP 的范围,这反过来又使其可访问在类 B.

【讨论】:

    【解决方案2】:

    Java Language Specification 声明:

    私有类成员或构造函数只能在包含成员或构造函数声明的顶级类(第 7.6 节)的主体内访问。

    由于AB 类是在BreakOOP 的主体中定义的,因此该规则适用并且B 可以看到A 的私有成员。

    至于 OOP 概念:由于 AB 是静态内部类,它们与真正的内部类所具有的 BreakOOP 没有特殊的生命周期关系(即您不需要实例的BreakOOP 来创建AB 的新实例,但它们仍然有一些特殊的关系,因为它们可以访问私有成员。如果他们不应该有那种关系,那么他们不应该是内部的类,但真正的顶级类。

    【讨论】:

      猜你喜欢
      • 2012-12-04
      • 2016-07-07
      • 1970-01-01
      • 2013-11-25
      • 2018-10-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-15
      相关资源
      最近更新 更多