2
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.nまだ7を印刷するのh = (Horse) ahですか?割り当て後、それはポイントするのと同じオブジェクトをah指す必要があり、nフィールドは5を指しますか?

4

2 に答える 2

8

まず、混乱を避けるためnに、クラスのフィールドをAnimal「 」と呼びましょう。Animal.n

メソッドとは異なり、フィールドはオーバーライドの対象ではありません。したがって、Horseクラスでは、7の値をオーバーライドしていると思われるかもしれませんが、Animal.n実際にはという新しい変数を宣言しています(混乱を避けるためにn呼び出しましょう)。Horse.n

つまり、実際には、Horse2つのフィールドで呼び出されるクラスがあります:Animal.nHorse.n。「」と言ったときにどのフィールドが表示されるかは、その時点での変数の静的nタイプによって異なります。

Horseタイプが、であるが、にアップキャストされているオブジェクトがある場合Animalnフィールドはを参照しAnimal.n、値は「5」です。したがってah.n、「5」です。

同じオブジェクトがあり、再びダウンキャストされたHorse場合、nフィールドはを参照しHorse.n、値は「7」になります。したがってh.n、「7」です。

明確にするために:確かに、hポイントするのと同じオブジェクトをahポイントします-ダウンキャストは、ポイントされているオブジェクトを変更しません。ただし、静的タイプは、オブジェクトのどのフィールドが要求されているかに影響します。

于 2011-02-06T01:35:36.490 に答える
0

Javaで作成するすべてのオブジェクト(インスタンスと呼ばれる)は、それが作成されたクラスを指します。これはオブジェクトの真のタイプであり、オブジェクトへの参照をキャストしても変更されません。同様に、オブジェクトを参照するすべての変数には、宣言された型があります。これは、コンパイラがオブジェクトを処理し、許可される操作を決定する方法です。

ただし、これら2つのタイプは緩く結合されているだけです。オブジェクト参照をキャストすると、宣言された型のみが変更されます。オブジェクトの動作には影響せず、コンパイラがオブジェクトを処理する方法にのみ影響します。

于 2011-02-06T04:56:33.610 に答える