22

Javaのポリモーフィズムを理解しようとしていますが、オブジェクトのダウンキャストについて1つ質問があります。この例では、スーパークラスの動物から継承する2つのサブクラスDogとCatがあるとします。

私が理解したことから、オブジェクトをダウンキャストする唯一の方法は、このオブジェクトがすでに次のように適切なタイプであるかどうかです。

Animal a = new Dog();
Dog d = (Dog) a;

これは正しく機能しますか?

しかし、それが何であるかを知らずに通常の動物を作成し、それを知ったときにそれをキャストしたい場合はどうすればよいですか?

Animal a = new Animal();
Dog d = (Dog) a;

これにより、実行時にClassCastExceptionがスローされますか?

私がそれを行うために見つけた唯一の方法は、通常の動物から犬を作成する新しいDogコンストラクターを作成することです。

Animal a = new Animal();
Dog d = new Dog(a);

public Class Dog extends Animal{
   public Dog(Animal a){
      super(a);
   }
}

だから私の質問は、これをどのように行うべきかということです。

  • 私はそれを最善の方法でやっていますか?
  • 私はこれをまったく行うべきではありません、もし私がそうしなければならないのなら、私のプログラムはよく考えられていないということですか?
  • 私が逃したより良い方法はありますか?

どうもありがとう!nbarraille

4

4 に答える 4

9

非ローカル条件に応じて変化する可能性のあるタイプのインスタンスを作成する場合は、Abstract Factoryを使用します(デザインパターンの本で説明されています)。

最も単純な形式では:

interface AnimalFactory {
    Animal createAnimal();
}

class DogFactory implements AnimalFactory {
    public Dog createAnimal() {
        return new Dog();
    }
}

また、参照の静的タイプとオブジェクトの動的タイプには違いがあることに注意してください。参照がAnimalある場合でも、元のオブジェクトがである場合は、Dogそれでも。のように動作しDogます。

于 2010-10-27T12:33:45.547 に答える
3

オブジェクトが実際にあるクラスにのみキャストする必要があります。したがって、Dog拡張するaがある場合は、Animalそれを(1であるため)にキャストできますが、すべてのsがsであるとは限らないため、にAnimalキャストしないでください。クラスには、クラスによって実装されていない追加のフィールドがある可能性があるため、キャストは意味がありません(これらの値を何に初期化するのですか?)。AnimalDogAnimalDogDogAnimal

于 2010-10-27T12:32:14.933 に答える
1

Javaは強く型付けされた言語であり、オブジェクトを拡張元の型(スーパークラスまたはインターフェース)にのみキャストできることを意味します。

たとえば、すべてのクラスのメソッドとフィールドをコピーするなど、「偽造」したとしても、オブジェクトを拡張しない型にキャストすることはできません。

public class Foo{

    public String phleem;

    public void bar(){

    }

}

public class Bar{

    public String phleem;

}

public interface Baz{

    public void bar();

}

上記のコードでは、FooオブジェクトをaBarまたはaのいずれかにキャストすることはできませんBazが、クラス構造はキャストできることを示唆しているようです。継承は含まれないため、aClassCastExceptionがスローされます。

于 2010-10-27T12:29:06.937 に答える
0

ここではダウンキャストについて話しているので、このシナリオでは常にスーパークラスを参照として使用する必要があり、子オブジェクトはそれによってポイントされる必要があります。この米ドルは基本的に工場のパターンです。

于 2010-11-04T09:40:12.720 に答える