这里的协方差是否安全?

nab*_*bil 2 java oop inheritance covariance

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);
}
Run Code Online (Sandbox Code Playgroud)

如果我们发送到foo(new Lion())会怎么样?我知道它会出错,但我需要解释

Edw*_*uck 5

Lion可以吃Meat,但它也可以吃任何种类的食物(如菠菜).

如果你Lion不能吃任何一种Food,那么它就不能被认为是一种实施方式了Animal.

在决定使用子类和类继承作为构造程序的方法时,这一点至关重要:您不要使您的子类比您的接口或超类更具体.

为了使子类能够以解决问题的方式工作(而不是创建问题),您需要遵守本指南:All subclasses must be functionally equivalent to the super-class (Liskov Substitution Principle) 这意味着提供对三个不同数据库的数据库访问的三个类是从公共类成为子类的良好候选者(或者可能共享一个公共接口),因为"功能"是"提供数据库访问".

你的Lion榜样不足之处在于,根据你对Animal现实世界的定义,狮子会不是一个,Animal因为现实世界的狮子会不吃任何一种Food.真实世界狮子的食物摄入能力比未知动物的一般定义更具特异性.正是这种功能上的差异使得将现实世界的狮子会建模为动物这个特定定义的子类是不合适的.

你可以通过Animal"吃食物"方法轻松解决这个问题,从而将"吃食物" IncompatibleFoodException的定义Animal改为"吃或拒绝食物".

  • 这是`@Override`注释派上用场的地方,因为它会显示`Lion.feed(Meat)`不会覆盖任何东西. (2认同)