2016-09-27 89 views
3

请考虑以下代码片段。打破Java中的封装和信息

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的一些基本概念。有人可以解释为什么这个编译?它背后的理由是什么?

+1

你我指的是'super.a',这是因为规范说明了这一点,因此任何私有成员都可以在顶层类的范围内看到,也就是在你的cas中的'BreakOOP'内e(我将不得不查阅JLS的相关部分)。 – Thomas

+0

内部类从父类获取可见性规则。这是为什么? - 直到讨论,这只是它在java中的方式。因此,从B访问super.a就像BreakOOP类中的两个私有变量。如果您想要更广泛的保护,则必须将它们移到不同的编译单元中。 – mtj

+0

[在子类中使用super关键字访问超类专用字段]可能的副本(http://stackoverflow.com/questions/31478718/access-to-superclass-private-fields-using-the-super-keyword-in -a-subclass) –

回答

1

Java Language Specification状态:

私有类成员或构造方法只在顶层类(第7.6节)包围的成员或构造的声明体是可访问的。

由于类ABBreakOOP的身体规则适用和B可以看到A私有成员中定义。

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