为什么无法使用父引用访问子字段

K.T*_*ess 1 java inheritance

class A {
    int super_var = 1;
}

class B extends A {
    int sub_var = 2;
}

public class Demo{
    public static void main(String []args){        
        A a = new B();
        System.out.print(a.sub_var); //compile error
    }
}
Run Code Online (Sandbox Code Playgroud)

为什么这会以编译错误结束?引用(a)引用B的Object它有sub_var,为什么它受到限制?为什么参考(a)只能访问A中的字段?

Chr*_*ian 5

假设您有这些课程:

public class Animal() {
    // ...
}

public class Fish extends Animal() {
    public void swim() {...}
}
Run Code Online (Sandbox Code Playgroud)

如果您宣布Animal:

Animal x = new Fish();
Run Code Online (Sandbox Code Playgroud)

你调用了这个swim()方法

x.swim();
Run Code Online (Sandbox Code Playgroud)

你期望它能起作用吗?我不这么认为,因为不是每个动物都可以游泳.这就是为什么你必须明确指出动物xFish:

((Fish) x).swim();
Run Code Online (Sandbox Code Playgroud)

在您的情况下,如果您想调用该方法,则应指定(在技术上,它称为强制转换)类型:

System.out.print(((B)a).sub_var);
Run Code Online (Sandbox Code Playgroud)

注意:

  • 这适用于方法和变量.我在示例中使用了一种方法,因为它更具说明性.

编辑:

我们来看看这个例子:

Animal x;

if (some_condition)
    x = new Fish();
else
    x = new Cat();

x.swim();
Run Code Online (Sandbox Code Playgroud)

存在此限制,因为Java在执行时不知道分配给x的对象是否具有该方法swim().因此,为了避免这种情况,您必须转换为相应的类型以调用超类中不存在的方法.