设计模式-设计原则-里式替换原则

里氏替换原则

概念

对于继承的思考

  1. 继承包含这样一层含义:父类中凡是已经实现好的方法,实际上是在设定规范和契
    约,虽然它不强制要求所有的子类必须遵循这些契约,但是如果子类对这些已经实现的方法任意修改,就会对整个继承体系造成破坏。
  2. 使用继承会给程序带来侵入性,程序的可移植性降低增加对象间的耦合性
  • 如果一个类被其他的类所继承则当这个类需要修改时,必须考虑到所有的子类,并且父类修改后,所有涉及到子类的功能都有可能产生故障
  1. 问题提出:在编程中,如何正确的使用继承?=>里氏替换原则

特点

在这里插入图片描述

凡是基类出现的地方 都能使用子类进行替换

  1. 所有引用基类的地方 必须能透明地使用其子类的对象
  2. 使用继承时 子类尽量不要重写父类的方法
  3. 继承实际让两个类耦合增强,适当情况可以通过聚合、组合、依赖来解决问题

场景介绍

类B在继承类A时可能 无意识重写了类A的方法导致错误(如函数重名等)


违反–里氏替换原则

在这里插入图片描述

如图:类B在继承类A时 可能会重写修改类A的所有方法(造成侵入 可能破坏功能)

public class LisKov {
    public static void main(String[] args) {
        A a = new A();
        System.out.println("11 - 3 = "+ a.func1(11,3));

        System.out.println("-----------");

        B b = new B();
        System.out.println("11 - 3 =" + b.func1(11,3));
        System.out.println("11 + 3 + 9" + b.func2(11,3));
    }
}

class A {
    //返回两个数的差
    public int func1(int num1, int num2){
        return num1 - num2;
    }
}
//此时B类继承了A
//增加一个新功能:完成两个数相加,然后和9相加
class B extends A{

    //在继承时无意识完成了 重写
    public int func1(int num1, int num2){
        return num1 + num2;
    }
    public int func2(int num1, int num2){
        return func1(num1, num2) + 9;
    }
}

运行结果

在这里插入图片描述

可以看到类A的fun1任然按照类A定义的步骤执行

但类B因为无意中重写了父类的方法,造成原有功能出现错误。

在实际编程中,我们常常会通过重写父类的方法完成新的功能,这样写起来虽然简单,但整个继承体系复用性会比较。特别是运行多态比较频繁的时候


遵循–里氏替换原则

在这里插入图片描述

如果一定要产生继承关系,可以将B类提升至于A类同级共同继承基类

如果B类一定要使用A类的方法 需要将A类与B类进行组合

public class LisKov {
    public static void main(String[] args) {
        A a = new A();
        System.out.println("11 - 3 = "+ a.func1(11,3));

        System.out.println("-----------");

        B b = new B();
        //此处为B类实现的自己专属功能
        System.out.println("11 + 3 = " + b.func1(11,3));
        System.out.println("11 + 3 + 9 = " + b.func2(11,3));
        //通过B类调用A类重写的方法
        System.out.println("11 - 3 = " + b.func3(11,3));
    }
}

//抽离出公共基础类
class Base{
    public int func1(int a,int b){
        return a - b;
    }
}

//类A继承基础类  重写func1方法完成自己的功能
class A extends Base{
    //返回两个数的差
    public int func1(int num1, int num2){
        return num1 - num2;
    }
}
//此时B类继承Base 又一次重写func1方法  修改为自己的功能
class B extends A{

    //使用组合方式 调用A对象方法
    private A a = new A();

    //B类在这里 重写为自己的功能
    public int func1(int num1, int num2){
        return num1 + num2;
    }
    public int func2(int num1, int num2){
        return func1(num1, num2) + 9;
    }

    public int func3(int num1, int num2){
        return this.a.func1(num1, num2);
    }
}

运行结果

在这里插入图片描述

类Bfunc1实现了自己的功能 同时也能正确使用类A的fun1功能

PS:笔者认为上述里氏替换原则使用面向接口编程手段会更灵活

本文章用来记录自己学习过程–来源:尚硅谷

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值