Этот вопрос является продолжением 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.