- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
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())
会发生什么?我知道它会出错,但我需要解释
最佳答案
您的狮子
可以吃肉
,但它也可以吃任何种类的食物(例如菠菜)。
如果您的 Lion
不能吃任何类型的 Food
,那么它就不能被视为 Animal
的实现。
在决定使用子类化和类继承作为构建程序的方法时,理解这一点至关重要:不要使子类比接口(interface)或父类(super class)更具体。
要使子类化以解决问题(而不是制造问题)的方式工作,您需要遵守以下准则:All subclasses must be functionally equivalent to the super-class (Liskov Substitution Principle)
这意味着提供对三个不同数据库的数据库访问的三个类很适合作为公共(public)类的子类(或者可能共享公共(public)接口(interface)),因为“功能”是“提供数据库访问”。
您的狮子
示例的不足之处在于,根据您对现实世界中动物
的定义,狮子不是动物
,因为它是真实的世界狮子不吃任何种类的食物
。现实世界中的狮子的进食能力比未知动物的一般定义更为具体。正是这种功能差异使得将现实世界中的狮子建模为动物的特定定义的子类并不合适。
您可以通过让 Animal
“吃食物”方法抛出 IncompleteFoodException
轻松解决此问题,这会将 Animal
的定义从“吃食物”的东西到“吃或拒绝食物”的东西。
关于java - 协方差在这里安全吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9950501/
在我的设置中,我试图有一个界面 Table继承自 Map (因为它主要用作 map 的包装器)。两个类继承自 Table - 本地和全局。全局的将有一个可变的映射,而本地的将有一个只有本地条目的映射。
Rust Nomicon 有 an entire section on variance除了关于 Box 的这一小节,我或多或少地理解了这一点和 Vec在 T 上(共同)变体. Box and Vec
我是一名优秀的程序员,十分优秀!