所有派生类的行为功能必须和使用者对其基类的期望保持一致,如果派生类达不到这一点,那么必然违反里氏替换原则。在实际的开发过程中,不正确的派生关系是非常有害的。伴随着软件开发规模的扩大,参与的开发人员也越来越多,每个人都在使用别人提供的组件,也会为别人提供组件。最终,所有人的开发的组件经过层层包装和不断组合,被集成为一个完整的系统。每个开发人员在使用别人的组件时,只需知道组件的对外的接口,那就是它全部行为的集合,至于内部到底是怎么实现的,无法知道,也无须知道。所以,对于使用者而言,它只能通过接口实现自己的预期,如果组件接口提供的行为与使用者的预期不符,错误便产生了。里氏代换原则就是在设计时避免出现派生类与基类不一致的行为。
4.5 如何正确地运用里氏代换原则
里氏代换原则目的就是要保证继承关系的正确性。我们在实际的项目中,是不是对于每一个继承关系都得费这么大劲去斟酌?不需要,大多数情况下按照“Is-A”去设计继承关系是没有问题的,只有极少的情况下,需要你仔细处理一下,这类情况对于有点开发经验的人,一般都会觉察到,是有规律可循的。最典型的就是使用者的代码中必须包含依据子类类型执行相应的动作的代码:
动物类Animal:
public class Animal{
String name;
public Animal(String name) {
this.name = name;
}
public void printName(){
try{
System.out.println('I am a ' + name + '!');
}catch(Exception err){
System.out.println('An error occured!');
}
}
}
猫类Cat:
public class Cat extends Animal{
public Cat(String name){
super(name);
}
public void Mew(){
try{
System.out.println('Mew~~~ ');
}catch(Exception err){
System.out.println('An error occured!');
}
}
}
狗类Dog:
public class Dog extends Animal {
public Dog(String name) {
super(name);
}
public void Bark(){
try{
System.out.println('Bark~~~ ');
}catch(Exception err){
System.out.println('An error occured!');
}
}
}
测试类:TestAnimal
public class TestAnimal {
public void TestLSP(Animal animal){
if (animal instanceof Cat ){
Cat cat = (Cat)animal;
cat.printName();
cat.Mew();
}
if (animal instanceof Dog ){
Dog dog = (Dog)animal;
dog.printName();
dog.Bark();
}
}
}
象这种代码是明显不符合里氏代换原则的,它给使用者使用造成很大的麻烦,甚至无法使用,对于以后的维护和扩展带来巨大的隐患。实现开闭原则的关键步骤是抽象化,基类与子类之间的继承关系就是一种抽象化的体现。因此,里氏代换原则是实现抽象化的一种规范。违反里氏代换原则意味着违反了开闭原则,反之未必。里氏代换原则是使代码符合开闭原则的一个重要保证。
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-21726-9.html
首先得有
哪怕微小的帮助也行
你也不用再这混淆视听