面向对象设计原则——里氏替换原则

里氏替换原则LSP(Liskov Substitution Principle)主要阐述了有关继承的一些原则。子类可以扩展父类的功能,但不能改变父类原有的功能,如果重写了父类的方法,就会降低整个继承体系的复用性,如果违背了里氏替换原则,就很有可能出现运行错误

这里以一个鸟的例子来阐述:

首先定义一个超类鸟,它具有飞行速度的属性和飞的功能,然后设计两个子类,一个是燕子,一个是企鹅,这两个动物都是鸟类,但是企鹅不会飞,首先我们以普通的方式来演示继承关系,并实现飞行测试

public class Bird {
    double speed;

    //d的距离需要飞行的时间
    public double getSpeedTime(double d) {
        return d / speed;
    }

    //设置鸟的飞行速度
    public void setSpeed(double speed) {
        this.speed = speed;
    }
}
public class Swallow extends Bird {
}
public class Penguin extends Bird {

    @Override
    public void setSpeed(double speed) {
        super.speed = 0;
    }
}

public class Main {
    public static void main(String[] args) {

        double d = 100;
        Bird bird = new Swallow();
        Bird bird1 = new Penguin();

        bird.setSpeed(100);
        System.out.println(bird.getSpeedTime(d));
        System.out.println(bird1.getSpeedTime(d));
    }
}

这样运行的结果如下图,企鹅需要的时间是Infinity,这是不符合逻辑的

下面来解决此问题,也就是李氏替换原则,不要重写,给企鹅定义自己的方法,也就是走

 

public class Animal {
    //这里有一些动物的属性和方法就不一一列出了
}
public class Bird extends Animal{
    double speed;

    //d的距离需要飞行的时间
    public double getSpeedTime(double d) {
        return d / speed;
    }

    //设置鸟的飞行速度
    public void setSpeed(double speed) {
        this.speed = speed;
    }
}
public class Swallow extends Bird {
}
/**
 * 这里直接继承Animal,因为它不具有飞的功能
 */

public class Penguin extends Animal{

    double walk;

    public void setSpeed(double walk) {
        this.walk = walk;
    }
    public double getSpeedTime(double d) {
        return d / walk;
    }
}

public class Main {
    public static void main(String[] args) {

        double d = 100;
        Swallow swallow = new Swallow();
        Penguin penguin = new Penguin();

        swallow.setSpeed(100);
        penguin.setSpeed(20);
        System.out.println(swallow.getSpeedTime(d));
        System.out.println(penguin.getSpeedTime(d));
    }
}

运行结果:

总结一句话,里氏替换主要解决,什么时候应该使用继承,什么时候不应该使用继承的问题!

相关推荐
©️2020 CSDN 皮肤主题: 技术黑板 设计师:CSDN官方博客 返回首页