この質問は、thisのフォローアップです。私は、複数のベース由来のペアを含むクラス階層を定義しようとしています。例として、クラスAnimal
とクラスFood
があるとします。 Animal
には、食べ物をパラメータとして食べ物の好みを示す純粋な仮想関数があります。リスコフ置換の原理と複数の階層
class Food
{
public:
virtual void printName() {
//......
}
};
class Animal
{
public:
Food *_preferredFood;
virtual void setFoodPreference(Food *food)=0;
};
これらの基本クラスだけを扱うコードを記述し、純粋仮想関数を呼び出す必要があります。たとえば、私はZooManager
クラスを持っています。これは、各動物の食物の好みを設定します。
class ZooManager
{
vector<Aninal*> animals;
public:
void setAllPreferences(vector<Food *> foods) {
assert(animals.size() == foods.size());
for(int i =0;i<animals.size();i++) {
animals[i]->setFoodPreference(foods[i]);
}
}
};
これまでのところとても良いです。今問題は、Food
とAnimal
には多くの異なる派生クラスがあることです。 Food
は、派生クラスFruit
およびMeat
を有し、Animal
は、派生クラスCarnivore
およびHerbivore
を有する。 Herbivore
は、食品の好みとしてFruit
のみを受け入れることができ、Carnivore
は、Meat
を受け入れることができます。
class Fruit : public Food
{
};
class Meat : public Food
{
};
class Carnivore: public Animal
{
public:
void setFoodPreference(Food *food) {
this->_preferredFood = dynamic_cast<Meat *>(food);
}
};
class Herbivore: public Animal
{
public:
void setFoodPreference(Food *food) {
this->_preferredFood = dynamic_cast<Fruit *>(food);
}
};
私はリスコフの置換原則に違反することなく、このためのクラス階層構造を作成できますか?この質問ではC++を使用していますが、Java固有の回答も歓迎します。
私は列挙型のソリューションが大好きではありません。主に、OOプログラミングを悪用するために頻繁に使用されるため、基本的に子クラス情報を基本クラスに入れているからです。私は 'Base'が' CHILD1、CHILD2、CHILD3'などの値を持つ 'Type'の列挙型を持つコードを見てきました。コードの束が' Base * 'を受け入れるように促し、基底型をチェックします。このようなコードは、誰もが多形性のすべての利点を得ることができると考えていることを反映しています。 'dynamic_cast'離れてもそれほど良くはありません。 – AndyG
@AndyG私はそれが素晴らしい*解決策ではないと言いました。上で書いたように、各動物種は、それがどのような種類の食物であるかを気にしています。基本的に、Foodクラスの背後にある抽象化は、* Foodsはかなり無駄な抽象であるため、*リークします。あなたが乾草を扱うのと同じ方法で生の肉を処理することは、非常に疑わしいことです。 – Yakk
合意。私はOPが自分たちをコーナーに構えていると思う。私のコメントは、あなたに同意することを意図したものではなく、なぜOP問題に対する「解決策」が望ましくないのかを強調する。 – AndyG