里氏替换原则
定义:使用父类的地方都能使用子类替换
要求:
1.子类的入参类型要比父类方法入参更宽(入参类型是父类入参类型的类型或者父类型)
2.子类的返回值类型父类方法要更窄(返回值类型是父类的返回类型或者子类型)
在java中就是要求子类不要Override父类的方法,保证子类实例化对象还是能调用到父类方法
代码示例如下
public static void main(String[] args) {
//初始我们只想有一个能“食物”的动物
Animal animal = new Animal();
Food food = new Food();
animal.eat(food);
//我们把这个动物增强,让它能吃鱼。但是我们还是希望它作为动物本身还是可以继续吃"食物"
Cat cat = new Cat();
cat.eat(food);
cat.eat(new Fish());
//我们把这个动物增强,让它能咩咩叫。但是我们还是希望它作为动物本身还是可以继续吃"食物"
//我们发现它已经不能继续吃“食物"了,而是开始吃草了。因为它无法调用到父类的方法了
Sheep sheep = new Sheep();
sheep.eat(food);
sheep.eat(new Grass());
}
public static class Animal {
protected String name;
public void eat(Food food) {
String subjectName = this.name == null ? "animal" : this.name;
System.out.println(String.format("%s eat food", subjectName));
}
public void setName(String name) {
this.name = name;
}
}
//符合LSP
public static class Cat extends Animal {
public void eat(Fish fish) {
System.out.println(String.format("%s eat fish", this.name));
}
public Cat() {
this.setName("cat");
}
}
//不符合LSP
public static class Sheep extends Animal {
@Override
public void eat(Food food) {
System.out.println(String.format("%s eat grass", this.name));
}
public void meimie(Grass grass) {
System.out.println(String.format("%s can miemie", this.name));
}
public Sheep() {
this.setName("sheep");
}
}
public static class Fish extends Food {
}
public static class Grass extends Food {
}
public static class Food {
}
网友评论