Java设计原则(六)里氏替换原则

里氏替换原则

定义

		如果对每一个类型T1的对象o1,都有类型为T2的对象o2,
使得以T1定义的所有程序P在所有的对象o1都替换成o2时,程序P的
行为没有发生变化,那么类型T2是类型T1的子类型。

定义扩展

		一个软件实体如果都使用一个父类的话,那一个定使用其子类,
	所有引用父类的地方必须能透明地使用其子类的对象,子类对象能
	替换父类对象,而程序逻辑不变。

引申意义

子类可以扩展父类的功能,但不能改变父类的原有功能。

含义1

子类可以实现父类的抽象方法,但不能覆盖父类的非抽象方法。

含义2

子类可以增加自己特有的方法

含义3

当子类的方法重载父类的方法时,方法的前置条件(方法的输入,入参)
要比父类的输入方法更宽松

含义4

当子类的方法实现父类的方法时(重写,重载或实现抽象方法),
方法的后置条件(方法的输出,返回值)要比父类的更严格或相等

优点

1. 约束继承泛滥,是开闭原则的一种体现。
2. 加强程序的健壮性,同时变更时也可以做到非常好的兼容性,提高
程序的维护性,扩展性。降低需求变更时引入的风险。

代码演示

在演示开闭原则的代码中,就很好的遵守了里氏替换原则,
下面使用另外一段代码演示里氏替换原则:

public class Rectangle {

    private long height;

    private long weight;

    public long getHeight() {
        return height;
    }

    public void setHeight(long height) {
        this.height = height;
    }

    public long getWeight() {
        return weight;
    }

    public void setWeight(long weight) {
        this.weight = weight;
    }
}

public class Square extends Rectangle{

    private long length;

    public long getLength() {
        return length;
    }

    public void setLength(long length) {
        this.length = length;
    }

    @Override
    public long getHeight() {
        return getLength();
    }

    @Override
    public void setHeight(long height) {
        setLength(height);
    }

    @Override
    public long getWeight() {
        return getLength();
    }

    @Override
    public void setWeight(long weight) {
       setLength(weight);
    }
}


//test1
public class SimpleTest {

    public static void main(String[] args) {
        Rectangle rectangle = new Rectangle();
        rectangle.setHeight(18);
        rectangle.setWeight(20);
        resize(rectangle);
    }

    private static void resize(Rectangle rectangle) {
        while (rectangle.getWeight() >= rectangle.getHeight()) {
            rectangle.setHeight(rectangle.getHeight() + 1);
            System.out.println("weight:" + rectangle.getWeight() + ",height:" + rectangle.getHeight());
        }
        System.out.println("Resize end, weight:" + rectangle.getWeight() + ",height:" + rectangle.getHeight());
    }
}

//test2
public class SimpleTest {

    public static void main(String[] args) {

        Square square = new Square();
        square.setLength(20);
        resize(square);
    }

    private static void resize(Rectangle rectangle) {
        while (rectangle.getWeight() >= rectangle.getHeight()) {
            rectangle.setHeight(rectangle.getHeight() + 1);
            System.out.println("weight:" + rectangle.getWeight() + ",height:" + rectangle.getHeight());
        }
        System.out.println("Resize end, weight:" + rectangle.getWeight() + ",height:" + rectangle.getHeight());
    }
}

在代码中,test1的测试结果是:

weight:20,height:19
weight:20,height:20
weight:20,height:21
Resize end, weight:20,height:21

test2的测试结果是:(截取了一段,方法执行了一个死循环)

weight:4599496,height:4599496
weight:4599497,height:4599497
weight:4599498,height:4599498
weight:4599499,height:4599499
weight:4599500,height:4599500

显然该代码不符合里氏替换原则:因为在Square在继承了Rectangle的时候重写了父类中的非抽象方法,违反了含义1:子类可以实现父类的抽象方法,但不能覆盖父类的非抽象方法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
本教程为授权出品教程1) 优秀的程序应该是这样的:阅读时,感觉很优雅;新增功能时,感觉很轻松;运行时,感觉很快速,这就需要设计模式支撑2) 设计模式包含了大量的编程思想,讲授和真正掌握并不容易,网上的设计模式课程不少,大多讲解的比较晦涩,没有真实的应用场景和框架源码支撑,学习后,只知其形,不知其神。就会造成这样结果: 知道各种设计模式,但是不知道怎么使用到真实项目。本课程针对上述问题,有针对性的进行了升级 (1) 授课方式采用 图解+框架源码分析的方式,让课程生动有趣好理解 (2) 系统全面的讲解了设计模式,包括 设计模式七大原则、UML类图-类的大关系、23种设计模式及其分类,比如 单例模式的8种实现方式、工厂模式的3种实现方式、适配器模式的3种实现、代理模式的3种方式、深拷贝等3) 如果你想写出规范、漂亮的程序,就花时间来学习下设计模式吧课程内容和目标本课程是使用Java来讲解设计模式,考虑到设计模式比较抽象,授课采用 图解+框架源码分析的方式1) 内容包括:设计模式七大原则(单一职责、接口隔离、依赖倒转、里氏替换、开闭原则、迪米特法则、合成复用)、UML类图(类的依赖、泛化和实现、类的关联、聚合和组合) 23种设计模式包括:创建型模式:单例模式(8种实现)、抽象工厂模式、原型模式、建造者模式、工厂模式。结构型模式:适配器模式(3种实现)、桥接模式、装饰模式、组合模式、外观模式、享元模式、代理模式(3种实现)。行为型模式:模版方法模式、命令模式、访问者模式、迭代器模式、观察者模式、中介者模式、备忘录模式、解释器模式(Interpreter模式)、状态模式、策略模式、职责链模式(责任链模式)。2) 学习目标:通过学习,学员能掌握主流设计模式,规范编程风格,提高优化程序结构和效率的能力。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值