问题描述
class Food{}
class Meat extends Food{}
class Animal{
void feed(Food f){}
}
class Lion extends Animal{
void feed(Meat m){}
}
void foo(Animal a){
Food f = new Food();
a.feed(f);
}
如果我们发送到foo(new Lion())
,将会发生什么?我知道它会出错,但是我需要解释
What will happen if we send to foo(new Lion())
?I know that it will get error but I need the explanation please
推荐答案
您的Lion
可以吃Meat
,但是它也可以吃任何类型的食物(例如菠菜).
Your Lion
can eat Meat
, but it can also eat any kind of food (like Spinach).
如果您的Lion
不能吃任何类型的Food
,则不能认为它是Animal
的实现.
If your Lion
could not eat any kind of Food
, then it could not be considered an implementation of Animal
.
在决定使用子类和类继承作为构建程序的一种手段时,理解这一点至关重要:您不会让子类比接口或父类更具体.
This is critical to understand when deciding to use sub-classing and class inheritance as a means of constructing programs: you don't make your subclasses more specific than your interface or super classes.
要使子类以解决问题的方式工作(而不是制造问题),您需要遵守以下准则: All subclasses must be functionally equivalent to the super-class (Liskov Substitution Principle)
这意味着提供对三个不同数据库的数据库访问权限的三个类很可能是公用类(或可能共享公用接口)的子类,因为功能"是提供数据库访问".
For sub-classing to work in ways that solve problems (instead of create problems), you need to abide by this guideline: All subclasses must be functionally equivalent to the super-class (Liskov Substitution Principle)
This means that three classes which provide database access to three different databases is a good candidate for being subclasses from a common class (or perhaps sharing a common interface), because the "functionality" is "offer database access".
您的Lion
示例不足之处在于,根据您对Animal
的定义,真实世界中的Lions不是Animal
s,因为现实世界中的Lions不吃任何种类的Food
.现实世界中的狮子在饮食能力上比对未知动物的一般定义更为具体.正是这种功能上的差异使得将真实世界的Lions建模为 Animal 的特定定义的子类是不合适的.
Where your Lion
example falls short is that according to your definition of Animal
a real world, Lions are not an Animal
s because real world Lions don't eat any kind of Food
. Real world Lions are more specific in their food eating ability than the general definition of an unknown animal. And it is this functional difference which makes modeling real world Lions as subclasses of this specific definition of Animal a bad fit.
您可以通过使Animal
食用食物"方法抛出IncompatibleFoodException
来轻松解决此问题,该方法将Animal
的定义从食用食物"更改为食用或拒绝食物"
You could easily fix this by having the Animal
"eat food" method throw an IncompatibleFoodException
, which changes the definition of an Animal
from something that "eats food" to something that "eats or rejects food".
这篇关于这里的协方差安全吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!