java中的私有范围和继承

时间:2017-01-20 07:51:15

标签: java

考虑这个简单的java代码:

class A {
    private int a = 10;

    public void print() {
        System.out.println(this.getClass().getName() + "    " + a);

    }
}

public class B extends A {
    public void p1() {
        print();
    }

    public static void main(String... args) {
        B b = new B();
        b.p1();
    }
}

如果要运行代码,则打印的值为B 10。 我的问题是,如果" a"当我们使用" private"修饰符,但方法是,然后现在在B类中有方法print()但是" a"因为它是私有的,所以不是该类的一部分,所以当我们试图通过说" a"的范围来尝试访问它时编译器不会抛出错误。是私人的?

4 个答案:

答案 0 :(得分:2)

print中的class A class B可以在public中找到,因为它class Bclass Aprint的孩子。< / p>

class A中的class A可以查看a中的所有字段,因为它是该类的方法。所以 函数可以看到 <script> function handleAuthClick(event) { gapi.auth.authorize( .. } </script> <script src="https://apis.google.com/js/client.js?onload=checkAuth"> </script> </head> <body> .. <button id="authorize-button" onclick="handleAuthClick(event)"> Authorize </button> ,因此可以看到编译过程。

答案 1 :(得分:1)

Field&#39; a&#39;是继承的。它不能直接从B类访问。 只有A类才能访问字段a。

答案 2 :(得分:0)

您将继承与可见性/访问混淆。

a内部B属性不可见;但它肯定是继承的,因为它仍然存在,因为B的实例包含Aclass B extends A)的实例,以及A的实例(print()方法存在的地方)始终包含a属性。

答案 3 :(得分:0)

JLS(8.3. Field Declarations)声明:

  

一个类继承自它的直接超类,并直接超级接口超类和超接口的所有非私有字段,这些字段既可以被类中的代码访问,也不会被类中的声明隐藏。

     

子类可以访问超类的私有字段 - 例如,如果两个类都是同一个类的成员。 然而,私有字段永远不会被子类继承。

但是,“继承”究竟意味着什么?

它的实际含义是(继承的)方法或字段的名称存在于子类的名称空间中。没有private方法。它不能在子类的名称空间中命名。

另一方面,超类的私有字段必须存在于子类的实例中。如果它不存在,则在超类中声明的使用私有字段的方法无法正常运行

但是接下来我们讨论了嵌套类; e.g。

public class Outer {
    class A {
       private int a;
       ...
    }
    class B extends A {
        private int b1 = a;  // Compilation error
        // field 'a' is still accessible!
        private int b2 = ((A this).a;   // OK!
    }
}

(是的......真的!!)

有趣的是,你得到的编译错误是:

Test.java:7: error: a has private access in Test.A
            private int b = a;

编译器编写者决定将这种情况描述为对私有变量的访问,而不是访问尚未继承的变量。

  

我的问题是,如果我们使用“private”修饰符但是方法是“a”不是继承的,那么现在在B类中有方法print()

......是的......

  

但是“a”不是该类的一部分,因为它是私有的,

没有!

这不是继承对字段的意义。字段a出现在B的每个实例中。只是它无法访问。你无法命名。

  

那么当我们试图通过说“a”的范围是私有来访问它时,编译器怎么不抛出错误?

因为它在那里。

意见:关于private字段和方法的“继承”的Java定义令人困惑。甚至反直觉。然而,事实就是如此。