downcasted对象指向哪里?

jav*_*ous 2 java downcast

public class Animal{

    int n = 5;

    public static void main(String[] args) {

        Animal a = new Animal();
        Animal ah = new Horse();
        Horse h = new Horse(); 

        System.out.println(h.n); // prints 7
        System.out.println(ah.n); // prints 5
        h = (Horse) ah;
        System.out.println(h.n); // prints 7

    }
}

class Horse extends Animal{

    int n = 7;

}
Run Code Online (Sandbox Code Playgroud)

我的问题:

为什么h.n还要打印7 h = (Horse) ah?在赋值之后它应该指向同一个ah点,n字段指向5?

mgi*_*uca 8

首先,让我们调用nAnimal" Animal.n" 的字段以避免混淆.

与方法不同,字段不受覆盖.因此,在您的Horse类中,您可能认为自己覆盖了Animal.n7 的值,实际上是在声明一个名为的新变量n(让我们称它为Horse.n避免混淆).

所以,你有一个叫Horse两个字段的类:Animal.nHorse.n.当你说" n" 时你得到哪个字段取决于当时变量的静态类型.

当你有一个类型为Horse,但是向上转换为a 的对象时Animal,该n字段引用Animal.n,并且值为"5".因此ah.n是"5".

当你拥有相同的对象时,再次向下转换为a Horse,该n字段引用Horse.n,并且值为"7".因此h.n是"7".

澄清:确实,h确实指向同一个指向的对象ah- 向下转换不会改变指向的对象.但是,静态类型确实会影响请求对象的哪个字段.

  • 讨论*为什么*字段不受覆盖:重写方法的重要性在于使用相同的接口但具有不同的实现.由于字段没有实现,只有类型和名称,覆盖不会执行任何操作.你可能想要的是Horse*构造函数*来指定`a = 7`,而不是声明一个新的int.这样,马只会有一个叫做"a"的字段,它明确地设置为7. (2认同)