2009-11-29 24 views

答えて

13

さて、ここで私が思いついた一つの良い一つですそれは実際に食べることができるタイプの食べ物です。だから、

Plant grass = new Plant(); 
Herbivore deer = new Herbivore(); 
deer.eat(grass); // ok 

Plant grass2 = new Plant(); 
Carnivore tiger = new Carnivore(); 
tiger.eat(grass2); // not ok. 

Meat deer2 = new Meat(); 
tiger.eat(deer2); // ok 

さて、最後の問題は、あなたがdeerHerbivoreであることを指定するとき、あなたがそれを食べるためにtigerためMeat作ることができない、ということです。しかし、一日の終わりには、これは面接の問題を解決するのに十分なはずですが、面接者を眠らせるわけではありません。

+2

あなたは1ヵ所で動物として、そして別の場所で食べ物として鹿を分類しているので、Downvoted。シカの同じ例は、両方とも可能です。虎はあなたの潅木をピーコッと食べている間に鹿を攻撃することができます。 –

+0

私はそれが解決しようとここに座っていた一つの問題だと知っています。私は新しいクラスを作り、Deerが2つの方法を取れるようにしなければなりません。忘れないでください:投稿が完全に役に立たず、他の人が見る価値がない場合にのみ、downvoteを覚えてください。おそらくもっと良い答えが必要です。 – mauris

+0

悪いモデル:TigerにGrassが与えられている場合、彼女はすべての動物のデフォルトの 'eat()'メソッドに戻ります。 TigerにGrassをフィードしようとすると、例外をスローする(または飼い主を投げる)関数を追加する必要があります。 –

0

ベストソリューションはありません。これは一般に主観的な質問のために受け入れられている方法であるため、これをコミュニティのwikiにすることができます。

私は実際に階層のための最良の親クラスを作ると思うだろうし、その文脈で "最高"が何を意味するのか理解しようとする。

すべてには、名前属性を持つことができるものがあります。しかし、そこにあるすべてのものは、食品です。もし何か食べれば、何か食べることができる私はFoodを親クラスにし、パラメータオブジェクトが現在のオブジェクトを食べることができるかどうかを確認するブール値を返すメソッドを与えます。

だから、私は最初のパスでなければならない場合がありますすべてのものに合った最も単純なクラス階層を思わ

class Food { 
    boolean canBeEatenBy(Food hungryObject) 
    String name 
} 

しかし、ほとんどのインタビューの質問の重要な部分は、あなたがインタビューした人の気持ちであり、正確な回答ではありません。

0

Double dispatch、おそらく?私は、サブクラス、スーパークラスの動物からの草食動物、肉食や雑食動物を作成し、とeatメソッドをオーバーライド

namespace Animals{ 

    // base class Animal 
    class Animal{ 

    public void eat(Food f){ 

    } 

    } 


    class Carnivore extends Animal{ 

     public void eat(Meat f){ 

     } 

    } 

    class Herbivore extends Animal{ 

     public void eat(Plant f){ 

     } 

    } 

    class Omnivore extends Animal{ 

     public void eat(Food f){ 

     } 
    } 

} 

namespace Food{ 

    // base class Food 
    class Food{ 

    } 

    class Meat extends Food{ 

    } 

    class Plant extends Food{ 

    } 

} 

:利用OOPのオーバーライド、サブクラスとスーパークラス -

8

Liskov Substitution Principleのポスターには、「アヒルのように見えたら、アヒルのようなものですが、バッテリーが必要な場合は、おそらく間違った抽象化があります。それは簡単な答えです。オブジェクトのいくつかは動物と食物の両方になる可能性があります。したがって、複数の継承のルートに行きたいと思わない限り、分類スキーマはすべて間違っています。

障害が解消されたら、残りの部分はオープンエンドで、他の設計原則を導入することができます。たとえば、オブジェクトを消費させるIEdibleインターフェイスを追加することができます。アスペクト指向で、肉食動物や肉食動物のためのデコレータを追加すると、適切なクラスのオブジェクトだけを消費することができます。

あなたの足で考えること、問題のさまざまな側面を見て説明すること、そしてうまくコミュニケーションすることがポイントです。そして、おそらくではなく、「1つの正解」の制限に縛られるのはではありません。ここで

1

は、その面接の質問にいくつかの考えです:

私はサイロン猫に同意:抽象化のこの種のは、(。それは、Javaに似たインターフェースだ場合でも)多重継承せずにうまく動作しません

Iだろう

動物:

  • 肉食
  • 彼女の相続の二つの形式を作成しますbivore

食べ物:

  • 野菜

動物の2種類の方法を "食べる"(私は雑食、食虫、および他の多くの種類を無視しています)は、様々な種類の食物に特化しています。 Javaのような言語を使用している場合、Foodがインタフェースになります。

6

私は彼にそれを傷つけるよう伝えたいと思います。それは恐ろしい抽象です。私たちは何の文脈も与えられていません。抽象概念は薄い空気から出てくるのではなく、「正しい」ものの「アイデア」から出てくる。最初に解決しようとしている問題を教えてください。この抽象を評価することができます。

コンテキストが指定されていない場合は、私自身は自分のことを仮定します。オブジェクトの種類によっては、他の種類のオブジェクトを食べることができます。それ以上のものはありません。

Eatableインターフェースを作成する(またはしたい場合は、Foodを呼び出すことができます)、そして私たちは今まで、私は仮定しますどのような何のコンテキストを持っていないので、それだけを印刷することを、おもちゃのコンソールプログラムです:

<X> ate <Y> 

だから、このインターフェースに必要なのはgetFoodName()メソッドです。

エラーチェックのために、あなたは、例えば、isGrassFoodType()isXFoodType方法の束を作成することができますが、isMeatFoodType()などEat(Eatable e)Cowの実装がisGrassFoodType()かどうかを確認するでしょう、そして失敗し、印刷物:

"Cow can't eat " + e.getFoodName() 
+2

-1。多態性はisXFoodTypeメソッドのように、実行時に型を調べるコードを書く必要がないためです。 – outis

+0

@outis:純粋主義はあなたの健康に悪いです。 – hasen

4

「オブジェクト指向プログラミング」という言葉を唱えたAlan Kayは、「OOPとは、メッセージング、ローカルの保持と保護、状態プロセスの隠蔽、すべてのものの極端な遅延バインディング」を意味しています。

データモデルのこの「問題」を解決しようとすると、遅延バインディングの反対のように聞こえます。なぜこれを強制するにはコンパイラが必要ですか?私はモデルを全く変更することについて心配しません。あなたが食べることができないものを渡したら、あなたは例外をスローします - 実生活のように、ほとんど!

1

いずれの動物も食物であり、いずれの野菜も食物である。実際、虎は牛によって食べられることがあります。 (プリオン病のスクレイピーは、感染した羊の神経組織を感染していない羊に供給することによって広がります。)

動物と野生の両方の種類ala Linnaeusを持つことができます。各種はシングルトンであり、典型的な食事を記録するのはList<Species>です。食物の階層を完全に取り除くと、物事を混乱させるだけです。

あなたの唯一の問題が各種のダイエット記録である場合、複数の種のクラスは不要です。 1つのインスタンス変数として種名を持つ単一の種族クラスと、別のインスタンス変数としてList<Species>を持つだけです。

0

システムが非常に大きくなると思うなら、私はプラント/肉と草食動物/肉食動物/オムニボアをサブクラス化することをお勧めします。

システムにgetFoodName()およびgetFoodType()というすべての植物/動物用の標準インターフェースがあることを確認するには、種と呼ばれる植物/動物の親クラスを作成することでこれを強制できます。

植物/肉と肉食動物/肉食動物のサブクラス化で見られる問題は、ミーアカットは肉食動物ですが、ライノを食べることはできません(より良い例があるかもしれません)ので、私は肉を食べ、植物は食べる。

もしそれが信じられないほど大きくならず、それについて神経症になりたければ、動物のサブクラスごとに許容できる食べ物の静的列挙を保存することができました。だから虎は鹿、昆虫などを保存することができます。

3

食べ物はインターフェースでなければならないので、植物と動物も食べ物になります。

概要動物クラスには、Foodをパラメータとして使用するeatメソッドが必要です。

動物のサブクラス:Carnivore、HerbivoreおよびOmnivoreは、それぞれ独自のバージョンのeatを持つ必要があります。解決

private void eat(Food food) 
{ 
     if(food instanceof Animal) 
     { 
      happilyEat(); 
     } 
     else 
     { 
      sniff&TurnAway(); 
     } 
} 

問題:肉食については、例えば

しかし、Carnivore、Herbivore、Omnivoreは、動物にタグを付ける適切な方法ではないため、より良いデザインのためにはインターフェースも必要です。

2

これはところでC#でジェネリックと簡単です:

public class Food 
{ 
} 

public abstract class Animal<T> : Meat where T:Food 
{ 
    public abstract void Eat(T food); 
} 

public class Herbivore : Animal<Plant> 
{ 
    public override void Eat(Plant food) 
    { 
     Console.WriteLine("Herbivore eats plants."); 
    } 
} 

public class Omnivore : Animal<Food> 
{ 
    public override void Eat(Food food) 
    { 
     Console.WriteLine("Omnivore eats food."); 
    } 
} 

public class Carnivore : Animal<Meat> 
{ 
    public override void Eat(Meat food) 
    { 
     Console.WriteLine("Carnivore eats meat."); 
    } 
} 

public class Plant : Food 
{ 
} 

public class Meat : Food 
{ 
} 

public class Cow : Herbivore 
{ 
} 

public class Tiger : Carnivore 
{ 
} 

public class Human : Omnivore 
{ 
} 

使用法:

var human = new Human(); 
    var tiger = new Tiger(); 
    var cow = new Cow(); 
    var plant = new Plant(); 

    human.Eat(cow); 
    tiger.Eat(human); 

    cow.Eat(tiger); // this doesn't compile 
    tiger.Eat(plant); // neither does this 
関連する問題