2017-04-10 15 views
-1

私はAnimalクラスを持ち、それを 'Sheep'と 'Cow'クラスに拡張したプログラムを作成しています。 私のプログラムでは、 'generate()'が呼び出されたときに新しい動物を作成する 'Farm'クラスもあります。私がプログラムを初期化するとき、各ファームには特定の動物が与えられて生成されます。もっと一般的なクラスからオブジェクトを生成する

私はこれを行ういくつかの方法を考えることができますが、どれも特に素晴らしいとは思われません。私が作ってみた一つの方法は、私のクラスは次のように定められていることです:

public class Farm { 
    public Animal typeOfAnimalToSpawn; 

    public Farm(Animal a) { 
     typeOfAnimalToSpawn = a; 
    } 

    public void generate() { 
     typeOfAnimalToSpawn.spawnMe(); 
    } 
} 

public abstract class Animal { 
    public abstract void spawnMe(); 
} 

public class Sheep { 
    public void spawnMe() { 
     new Sheep().create(); 
    } 

    public void create() { 
     // Spawn this sheep onto the field (By making it visible or something) 
     // Do whatever needs done when a sheep arrives 
    } 
} 

これは私がシンプルかつエレガントなソリューションを持っているだけを取ることができる何かのために夢中になって、複雑で入り組んだそうです。このシナリオでは、実際にSheepをタイプ(ファームの場合)とオブジェクト(作成の場合)の両方として使用しています。これに加えて、 'new Sheep()'を呼び出すことによって実際に羊が作られるわけではなく、何かが起こったときにcreateまた、動物のインスタンス全体を保存するだけで、将来の動物を産むための農場のタイプとして役立つとは思われません。

それは単に動物の種類ごとに農場持ってするのは簡単だろう:

public abstract class Farm { 
    public abstract generate(); 
} 

public class SheepFarm extends Farm { 
    public void generate() { 
     new Sheep(); 
    } 
} 

public class Sheep { 
    public Sheep() { 
     // Do whatever needs done when a sheep arrives 
    } 
} 

表面にいいと端正だが余分に必要とする、すべての新しい動物のための完全に役に立たないクラスがプログラムに追加。必ずしも理想的ではありません。

リフレクションとは別の方法がありますが、私は物事をやるためのより賢明な方法があると確信していますので、それを使用するのは嫌です。

私の質問は、このような状況に近づく最善の方法は何か、そして私が上に掲げた解決策よりも簡単な方法があるのですか?

私は完全に独学であるため、適切なやり方を知らず、Googleで自分自身で仕事をしなければならなかったが、ここでは完全に失敗した。私は、もちろん、「きちんとしたコードを書く方法を学ぶ」チュートリアルが付属していないWikipedia以外の一般的なプログラミングのパラダイムに関する情報をどこから探し始めるのかは分かりません。

私の質問が漠然としていても、右下であっても意味がない場合は、明確にするようお願いします。

+2

私はここで質問を見つけることができません。 –

+0

完全に私のせいです。何かを実際に尋ねるのを忘れた。私の質問は、このような状況に近づくための最良の方法は何ですか?また、私が上に掲げた解決策よりも簡単な方法がありますか? – Oberdiah

+0

私はここでの問題点についてはっきりしていませんが、オプション2でやっている 'Sheep'クラスの中でoption1で同じことをやってみることはできませんか? – developer

答えて

0

私はそれに行くかの方法が(ただし、あなたがAnimalクラスの抽象識別子を削除する必要があると思います)Farmのためのジェネリック型を使用することです:

public class Farm<E extends Animal> { 

    private E e; 

    public Farm() { 
     this.e = (E) new Animal(); 
    } 

    public void generate() { 
     e.spawnMe(); 
    } 

} 

あなたが慣れていない場合ジェネリック型では、私は間違いなくそれらを研究するだろう!

+0

それは本当に素晴らしいです!一般的なタイプはまさに私が探していたものです!ファームが実際に羊を生成する前に 'new Sheep()'を使用する必要があり、羊のコンストラクタコードをspawnMe()に移動させる必要があるため、まだ混乱しています。 – Oberdiah

+0

@Oberdiah残念なことに、抽象的なファクトリパターンを使用してさまざまなタイプの子オブジェクトを作成することはできませんが、ジェネリック型が使用方法になります。 –

+0

エンティティリストへの追加や、createMe()などの別のメソッドへのレンダリングの設定など、初期化コードの大部分を移動するのが一般的です。 下記の誰かが「新T()」について何かを投稿しました。これはいいですが、明らかな理由から可能ではありません。 – Oberdiah

0

あなたの最初の解決策はかなり効率的であるようです。私はFarm sheepfarm = new Farm(new Animal...)と入力するだけでよいと思います。幸運:)

関連する問題