10

このコードがあるとしましょう:

class Animal {
    int legs = 4;
    int head = 1;
}

public class Dog extends Animal {
    public static void main (String []args) {
        Dog dog = new Dog();
    }
}

super()引数のないコンストラクターの最初の行に暗黙的に配置されていることを認識しているため、コンストラクターが実行され、 のインスタンス変数が設定されることがわかっていAnimalますAnimal

Animalこの目的のために、これらの変数がスーパー コンストラクターによって初期化されると ( )、それらのインスタンス変数が Animal オブジェクトに保持されるか、サブクラスにコピーされるか( )を理解したいと思いますDog

最初のケースでは、オブジェクトAnimalは暗黙的にインスタンス化され、インスタンスがそれらの変数の 1 つにアクセスする必要があるsuper();ときはいつでも、インスタンスに保持されている(バックグラウンドで作成された) 変数へのアクセスが行われます。または 2 番目のケースで、オブジェクト Animal が一時的に作成される場合、すべてのインスタンス変数 ( 内) がインスタンスにコピーされ、一時的に作成された のインスタンスが削除されます。DogAnimalAnimalDogAnimal

個人的には、たとえば、Dogオブジェクトは、オブジェクトに直接接続されているオブジェクトに直接リンクされると思いAnimalます。

このようにですか?

4

4 に答える 4

16

object は 1 つだけで、すぐに (最初から)Dogインスタンスになります。のすべてのフィールドDog(ここにあるわけではありません)のすべてのフィールドがありAnimalます。

最初は、すべての変数がデフォルト値 (0、null など) に設定されます。次に、各クラスのコンストラクター本体に到達すると (スーパークラス コンストラクターを呼び出した後)、インスタンス変数初期化子が実行され、次にそのクラスのコンストラクター本体が実行されます。

オブジェクトは 1 つしかないため、コピーは必要ありません。たとえば、Animalコンストラクタを次のように記述するとします。

public Animal() {
    System.out.println(this.getClass());
}

...コンストラクタがまだ実行されていなくてもDog、オブジェクトはすでに であるため、出力されます。DogDog

于 2013-03-02T17:48:11.827 に答える
9

extendsおよび、変数はプライベートではないため、インスタンスからアクセスしDogます。AnimalheadlegsDog

実際には、次のことが起こります。

  • Dogインスタンスを作成します。これはAnimal
  • すべてのオブジェクト プロパティが作成および初期化されます ( head、および のプロパティの後Animalも同様) 。
  • の暗黙のコンストラクターDogが呼び出されます (それは を呼び出しますsuper())
  • の暗黙のコンストラクターAnimalが呼び出されます

そして結果は Object であり、これは ですがDog、暗黙的にもAnimalです。


オブジェクトがどのように見えるか (例のためにクラスはDog忘れましょう)。プロパティも持っているとしObjectましょう。Dogpublic String name;

以下は、Dog インスタンスのメモリ マップです。

Addr  Type     Name      Defined in:
------------------------
| 0 | int    | legs    | Animal
| 1 | int    | head    | Animal
| 2 | String | name    | Dog
------------------------
  • がある場合は、アドレス 1で変数としてAnimalアクセスし、head
  • がある場合、アドレス 2で変数としてDogアクセスし、name
  • がある場合は、アドレス 1の変数として にDogアクセスします。head

Animalクラスの本体で実行されるコードは、アドレスのみを参照できます0-1Dogクラスで実行されるコードは、アドレスにアクセスできます0-2。プロパティがprivateスーパークラスにある場合、そのアドレスはサブクラスでは禁止されます。

このメモリ マップにより、オブジェクトを非常に簡単にダウンキャストできます。同じメモリ マッピングが使用され、処理 (コードと可視性) のみが異なります。

少し明確になることを願っています。

于 2013-03-02T17:54:52.403 に答える
2

これらの変数がスーパー コンストラクター (Animal) によって初期化されると、それらのインスタンス変数は Animal オブジェクト内に保持されるか、サブクラス (Dog) にコピーされます。

まず、インスタンス変数はでオーバーライドされませんsub-class。それらは目に見えるだけです。犬のインスタンスではコピーされません。public、protected、または no-modifier のいずれかがマークされている場合は、Dog のインスタンスを使用して Dog クラスからアクセスできます。

于 2013-03-02T17:49:21.293 に答える
1

動物オブジェクトはなく、犬オブジェクトのみが作成されます。Dog オブジェクトには、Animal オブジェクトから継承された変数 feets、head があります。それらは、Dog オブジェクトのメンバーであるかのように動作します。Animal クラスのコンストラクターは、Dog で Animal クラスを拡張しているため呼び出されます。また、Animal は暗黙的に Object を拡張するため、Object クラスのコンストラクターは Animal から呼び出されます。

Java がこれらの呼び出しを処理する方法は Java の内部的なものであり、バージョンごとに異なる可能性がありますが、同じ動作を維持する必要があります。

于 2013-03-02T17:54:51.683 に答える