Использование композиции поверх наследования:
Вместо того, чтобы наследовать, основываясь на пищеварительной системе, разбейте пищеварение на собственный набор классов.
Во-первых, интерфейс, который описывает различные способы питания.
public interface IDigest
{
void Eat(Meat food);
void Eat(Plant food);
void Eat(Offal food); //lol nethack
}
Плотоядные животные едят мясо, иногда могут есть травы и не любят дерьма:
public class Carnivorous : IDigest
{
public void Eat(Meat food)
{
Console.Write("NOM NOM");
}
public void Eat(Plant food)
{
if(Starving)
Console.Write("Ugh, better than nothing.");
else
Vomit();
}
public void Eat(Offal food)
{
Vomit();
}
}
Травоядные привередливы и скорее умрут, чем съедят мясо (я знаю, сохраните ваши комментарии, это пример)
public class Herbivorous : IDigest
{
public void Eat(Meat food)
{
Vomit();
}
public void Eat(Plant food)
{
Console.Write("NOM NOM");
}
public void Eat(Offal food)
{
Vomit();
}
}
Всеядные едят что угодно. Посмотрите государственную ярмарку.
public class Omnivorous : IDigest
{
public void Eat(Meat food)
{
Console.Write("NOM NOM");
}
public void Eat(Plant food)
{
Console.Write("NOM NOM");
}
public void Eat(Offal food)
{
Console.Write("NOM NOM");
}
}
Все животные должны есть, поэтому они должны иметь пищеварительную систему наряду с другими системами.
public abstract class Animal
{
/* lots of other stuff */
public IConsume DigestiveSystem {get;set;}
/* lots of other stuff */
}
Хиппи - это класс животных с известными вкусами; он настраивает себя на создание экземпляров. Также возможно ввести поведение и системы извне.
public class Hippie : Animal
{
public Hippie()
{
/*stuff*/
DigestiveSystem = new Herbivore();
BodyOdorSystem = new Patchouli();
/*more stuff*/
}
}
И, наконец, давайте посмотрим, как хиппи съест бургер.
public static void Main()
{
Hippie dippie = new Hippie();
Meat burger = new Meat("Burger", 2/*lb*/);
dippie.DigestiveSystem.Eat(burger);
}
При моделировании сложных систем, таких как животные, я бы предпочел композицию, а не наследование в ЛЮБОЙ ДЕНЬ. Сложные системы могут быстро взорвать дерево наследования. Возьмите три системы животных: всеядное животное / травоядное животное / плотоядное животное, вода / воздух / земля и ночной / суточный. Давайте даже не будем беспокоиться о том, как решить, какая классификация станет первой точкой дифференциации для животных. Распространяем ли мы Animal сначала на Carnivore, сначала на WaterLiving или на Nocturnal?
Поскольку всеядное существо может жить в воздухе и предпочитать ночь (летучая мышь *), а также быть дневным существом (людьми), вы должны иметь путь наследования, который затрагивает каждый отдельный вариант. Это наследственное дерево с 54 различными типами (его рано, будьте добры). И животные намного сложнее, чем это. Вы могли легко получить дерево наследования, которое имело миллионы типов. Композиция по наследству, определенно.
* Новозеландская короткохвостая летучая мышь, например, всеядна.