java中的私有作用域和继承
考虑以下简单的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
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
的私有部分