3分钟了解里氏替换原则
它是什么?
我们来举个例子吧!
包起来
里氏替换原则是SOLID面向对象设计中的L,尽管它是 5 条原则中名称听起来比较吓人的一个,但实际上它很容易理解。
事实上,它非常简单,你只需大约 3 分钟就能理解它。
它是什么?
简单来说,LSP 规定同一超类的对象应该能够相互交换而不会破坏任何东西。
如果我们有一个Cat
和一个Dog
从Animal
类派生的类,则任何使用该类的函数都Animal
应该能够使用Cat
或Dog
并且正常运行。
我们来举个例子吧!
即使这个定义也解释得不太清楚,所以让我们把它付诸实践。通过代码,一切都会变得清晰。
按照真正的 OOP 方式,让我们创建一个Animal
超类和一个Dog
子Cat
类,并捕获他们最喜欢的食物种类。
public static class Animal {
public String favoriteFood;
public Animal(String favoriteFood) {
this.favoriteFood = favoriteFood;
}
}
public static class Dog extends Animal {
public Dog(String favoriteFood) {
super(favoriteFood);
}
}
public static class Cat extends Animal {
public Cat(String favoriteFood) {
super(favoriteFood);
}
}
Animal
现在我们想创建一个方法,让我们可以给这些小可爱们一些零食。不过我不想把这个方法放在类里,因为这是我喂食动物的方法,而不是动物的固有行为。类似这样Dog.feed
写或许能表达清楚,但我觉得feed(Dog)
这样更好,你觉得呢?
让我们创建这个方法并调用它GiveTreatTo
:
public static void GiveTreatTo(Animal animal) {
String msg = "You fed the " + animal.getClass().getSimpleName() + " some " + animal.favoriteFood;
System.out.println(msg);
}
看看这里,它GiveTreatTo
接受 anyAnimal
作为参数。由于我们的Animal
构造函数指定了动物最喜欢的食物,所以我们几乎可以依赖这些数据始终存在。
这意味着我们不必为每种动物(例如GiveTreatToDog
和GiveTreatToCat
)都创建一个方法。因为我们实现了 LSP,所以我们只有一个方法。让我们看看它的实际效果:
public static void main(String[] args) {
Dog rover = new Dog("bacon");
Cat bingo = new Cat("fish");
GiveTreatTo(rover);
GiveTreatTo(bingo);
}
现在,如果我们正确实现了 LSP,这个程序应该可以正常运行。让我们检查一下输出:
You gave the Dog some bacon
You gave the Cat some fish
太棒了!这个原则的另一个好处是,我们可以添加越来越多的子类,Animal
而GiveTreatTo
方法不需要任何修改。
包起来
是不是感觉很直观?就像编程和计算机科学中的许多概念一样,名字掩盖了它的简洁性。现在,去实现你的子类可替换吧,感谢 Barbara Liskov 博士提供的如此实用的原则。
鏂囩珷鏉ユ簮锛�https://dev.to/erikwhiting88/liskov-substitution-principle-in-3-minutes-2dc6