Ваш Lion
может съесть Meat
, но он также может съесть любую пищу (например, шпинат).
Если ваш Lion
не может съесть какой-либо Food
, то онне может рассматриваться как реализация Animal
.
. Это важно понимать, когда вы решаете использовать подклассы и наследование классов как средство конструирования программ: вы не делаете свои подклассы более конкретными, чем вашиинтерфейс или суперклассы.
Чтобы подклассификация работала способами, которые решают проблемы (вместо того, чтобы создавать проблемы), вам необходимо соблюдать это правило: All subclasses must be functionally equivalent to the super-class (Liskov Substitution Principle)
Это означает, что триклассы, которые обеспечивают доступ к базе данных к трем различным базам данных, являются хорошим кандидатом на роль подклассов общего класса (или, возможно, общего интерфейса), поскольку «функциональность» - это «предлагать доступ к базе данных».
Где ваш Lion
пример не соответствует тому, что согласно вашему определению Animal
реального мира, Львы не являются Animal
с, потому что в реальном мире Львы не едятвид Food
.Львы в реальном мире более специфичны в еде, чем в общем определении неизвестного животного.И именно это функциональное различие делает моделирование реальных львов подклассами этого конкретного определения Animal плохой подгонки.
Вы можете легко это исправить, если Animal
"съесть пищу«метод выбросить IncompatibleFoodException
, который меняет определение Animal
с чего-то, что« ест пищу », на то, что« ест или отвергает пищу ».