downcast对象指向哪里?

时间:2011-02-06 01:28:12

标签: 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;

}

我的问题:

为什么h.nh = (Horse) ah之后仍然打印7?在赋值之后它应该指向ah个点且n个字段指向5的同一个对象?

2 个答案:

答案 0 :(得分:8)

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

与方法不同,字段不受覆盖。所以在你的Horse课程中,你可能认为你用{7}覆盖了Animal.n的值,你实际上是在声明一个名为n的新变量(我们称之为Horse.n以避免混淆)

实际上,您有一个名为Horse的课程,其中包含两个字段:Animal.nHorse.n。当您说“n”时,您会得到哪个字段取决于当时变量的 static 类型。

如果您的对象的类型为Horse,但最高为Animal,则n字段引用Animal.n,其值为“5” 。因此ah.n是“5”。

当您拥有相同的对象时,再次向下转换为Horsen字段引用Horse.n,其值为“7”。因此h.n是“7”。

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

答案 1 :(得分:0)

您在Java中创建的每个对象(称为实例)都指向创建它的类。这是对象的真实类型,并且在对其进行转换时不会更改。类似地,引用对象的每个变量都具有声明的类型。这是编译器处理对象并确定允许的操作的方式。

然而,这两种类型只是松散耦合。转换对象引用仅更改声明的类型。它不会影响对象的行为方式 - 只有编译器如何处理它。