java中的私有作用域和继承

java中的私有作用域和继承,java,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

考虑以下简单的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();
    }
}
如果要运行代码,则打印的值为b10。
我的问题是,如果当我们使用“private”修饰符时“a”不是继承的,但是方法是继承的,那么类B中现在有方法print(),但是“a”不是类的一部分,因为它是私有的,那么当我们试图通过说“a”的作用域来访问它时,编译器如何不抛出错误呢是私有的吗?
打印
A类
可以在
B类
中访问,因为它是
公共的
B类
A类
的子类


但是
A类中的
print
可以看到
A类中的所有字段,因为它是该类的一种方法。因此,该函数可以看到
a
,因此编译通过。

字段“a”被继承。不能直接从B级进入。
只有A类可以访问字段A。

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

a
属性在
B
中不可见/无法直接访问;但它肯定是继承的,因为
B
的实例包含
A
类B扩展了A
),而
A
(其中
print()
方法存在)的实例总是包含
A
属性

JLS()声明:

类从其直接超类和直接超接口继承超类和超接口的所有非私有字段,这些字段都可由类中的代码访问,并且不会被类中的声明隐藏

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

但是,“继承”到底是什么意思

它实际上意味着(继承的)方法或字段的名称出现在子类的名称空间中。
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”的作用域是私有的来访问它时,编译器如何不抛出错误呢

因为它就在那里



观点:Java对
private
字段和方法的“继承”定义令人困惑。甚至违反直觉。然而,这就是问题所在。

是的,这个问题很明显(这是一个主观的术语),但它写得很好,并且有一个简单易懂的例子支持。因此,我不理解向下投票。
操作符沿着类层次结构向上移动,直到找到方法的定义为止
print()
没有被复制到
B
@Bathsheba-我试了3次来解析那句4行的句子。。。结果失败了。你一定在使用我不知道的“写得好”的其他定义:-)当然,这一定是重复的。我的[java]重复列表没有我的[javascript]重复列表那么广泛……很可能是概念上的重复。字段“a”没有被B继承,私有修饰符没有被继承,只有方法被继承。@StephenC非常奇怪,我一直认为私有修饰符不会像javadoc所说的那样被继承:子类不会继承其父类的私有成员。但是,如果超类具有访问其私有字段的公共或受保护方法,则子类也可以使用这些方法。但是私有修饰符可以通过封装来访问。类B有字段“a”,但不可访问-这是事实。从实现的角度来看:私有字段和方法是“继承的”,但它们不可见。从继承概念的角度来看,字段“a”不是继承的。@MateuszBalbus所以如果我尝试其他一些新方法,比如public void printB(){System.out.println(a);},编译不会失败吗?它会失败,因为“a”不可访问,但类包含它。您可以使用Java反射API来检索它。但是,该方法现在属于类B,不是吗?实际上,函数print没有移动到类B,但它可以从类B访问。因此,函数print可以从类B访问,私有属性a可以从函数print访问。如果我理解正确,现在print()是B类中的一个方法,那么另一个方法不应该也可以访问“a”吗?当然可以。
B
的其他方法被禁止这样做,因为
a
是类
a
的私有部分