2016-11-16 7 views
1

私は既存のオブジェクトのサブクラスを作成する私の会社のAPIを使って作業しています。ここでの注意点は以下のとおりです。Javaでオブジェクトをキャストする方法

  • 私は動物のサブクラスとしてスーパー
  • 私はスーパークラスのオブジェクトが

私が最も一般的に見例インスタンス化される方法を変更することはできません

  • される犬を変更することはできませんので、私はそれを使用します。あなたがAPIで、このクラスがあるとしましょう:

    //API class, which I cannot modify 
    public class Animal(){ 
        public void eat(){ 
         //All animals can do this 
        } 
    } 
    

    今、私は動物にいくつかのメソッドを追加し、このようなクラスを作成したいと思います。

    //My subclass, which I can modify 
    public class Dog extends Animal(){ 
        public void fetch(){ 
         //Only dogs can do this 
        } 
    } 
    

    ここで、私は動物のインスタンス(犬ではないもの)を持っているとしましょう。私は基本的にそれを犬に落とす必要があります。私はダウンキャスティングがJavaで直接サポートされていないことを知っていますが、これに対する回避策はありますか?

    public class AnimalExample{ 
        public static void main(String[] args){ 
         Animal animal = MyApi.getAnAnimal(); 
         //Dog dog = (Dog) animal; ---throws a runtime error 
         Dog dog = Dog.getDog(animal); //Maybe something like this? 
    
         //Then I should be able to call both eat() and fetch() 
         dog.eat(); 
         dog.fetch(); 
        } 
    } 
    

    ここでも、ダウンキャストは直接サポートされていないことを理解しています。しかし、これにはいくつかの回避策が必要であり、私はそれを理解することはできません。私はラッパークラス(例:DogWrapper)を使用することができることを知っていますが、これは数十のスーパークラスメソッドを頻繁に呼び出すので、私が望むよりも少し難しいでしょう。

    UPDATE:私はそれがまだ犬ではないことを理解していますが、それを犬に変換する方法があるのだろうかと思っていました。基本的には、人々が言っ​​ていることから、私は手動で(各属性/メソッドを1つずつコピーするか)Wrapperクラスを使用するかのどちらかに変換する必要があります。 Wrapperクラスのほうがはるかに面倒ではないようですので、残念ながら私はそのルートに行かなければなりません。したがって、DogWrapperfetch()メソッドとgetAnimal()メソッドを持ちます。だからDogを食べたいなら、dog.getAnimal().eat()に電話しなければならない。私はそれをやることを避けていましたが、周りには道がないと思います。誰かがそれより簡単な何かを見ますか?

  • +2

    「私は基本的に犬にそれをダウンキャストする必要がある」しかし、それは*ありません* 'Dog'です。非犬に「犬」のように行動するように求めることはできません。ダウンキャスト*はサポートされていますが、安全に実行されます...キャストは、実行時の型が要求された型と互換性がある場合にのみ成功します。 'dog.fetch()'は何をすると思いますか? 'Dog'で宣言されたいくつかのフィールドを使って、実際のオブジェクトにはないものはどうでしょうか? –

    +0

    だから、あなたは「犬」ではない「動物」をいくつか持っていますが、とにかく「犬」のように扱いたいと思っています。それを自分で「犬」に変換する必要があります。 Javaはこれを行う方法を自ら知ることができません。 (なぜ、これは有用だと思いますか?動物が「犬」でない場合は、「犬」に固有のメソッドを呼び出すとどうなりますか?) – Jesper

    +0

    if(animal instanceof Dog){dog dog =(Dog)animal} else {//問題の事例を処理する} – mdewit

    答えて

    0

    Animalを受け取り、オブジェクトのDog部分をデフォルトまたは必要に応じてインスタンス化するコンストラクタを持つことができます。

    public Dog (Animal animal) { 
        super(); // any instantiation that has to be done for animal 
        // Dog instantiation 
        // Use animal properties as required 
    } 
    Dog dog = new Dog(animal); 
    

    はまた、あなたがDog.getDog(animal)を述べたように、静的メソッドを持つことはオプションで、あなたのコーディングの好みによって異なります。

    +0

    これの問題は、私が_original_ 'Animal'オブジェクトをもう使用していないことです。 「Dog」のインスタンスは、新しい「Animal」です。だから、 'dog.eat()'を呼び出すと、最初に作成された元の 'Animal'ではなく' super() 'で作成された' Animal'の 'eat()'メソッドを呼び出します。 –

    +0

    @JakeFairbairnあなたが言っていることは真実ではありません。元の動物オブジェクトで行う唯一のことは、必要なプロパティをコピーすることです。元のオブジェクトからの参照が使用されないように詳細コピーを行います。これにより、新しいDogオブジェクトがインスタンス化され、dog.eatを呼び出すと新しいオブジェクトになります – tinker

    0

    Dogが必要なメソッドを作成するとしますが、Animal APIを拡張することを想定しています。確かに、私はそうのような署名を作ることができる:

    public void doFetch(Dog dog) 
    

    しかし、私はAnimal APIを拡張したい、私が言ったように。現在、AnimalDogでない場合、私はフェッチできません。このことを念頭に置いて、私は次の操作を行うことができます

    public void doFetch(Animal fetcher) { 
        if(fetcher instanceof Dog) { 
         Dog dog = (Dog) fetcher; 
         ... //Do fetchy things 
         return; 
        } 
        //If we reach this point, then the animal is not a dog 
        throw new IllegalArgumentException("fetcher is not a Dog!"); 
    } 
    

    は、今度は仮定しましょう、あなたの場合のように、私は犬ではありませんが、私はそれが何らかの理由でDogになりたいAnimalを持っています。この場合、何らかの翻訳者を使ってAnimalを犬に変換できます。私はDogクラス自体でstatic方法として、このようなものを定義することを好む:

    //Breaks the laws of nature by making a Dog from any Animal. 
    public static Dog fromAnimal(Animal animal) { 
        Dog dog = new Dog(); 
        //Here you would set all the properties of the animal, e.g.: 
        dog.setName(animal.getName()); 
        ... 
        return dog; 
    } 
    
    +0

    新しい 'Dog'オブジェクトに' Animal'のコピーを作成することを考えましたが、それは本当に面倒です。 'Animal'に変更が加えられた場合、' Dog'に反映されません。加えて、すでに100人ものセッターが走っていなければならない。これはすでに醜いものだ。 –

    関連する問題