首页 > 其他分享 >面向对象的7种设计原则(5)-里氏代换原则

面向对象的7种设计原则(5)-里氏代换原则

时间:2022-09-20 15:55:24浏览次数:60  
标签:Foo 原则 里氏 int 子类 class 代换 父类 public

定义

里氏代换原则(Liskov Substitution Principle LSP)面向对象设计的基本原则之一。 里氏代换原则中说,任何基类可以出现的地方,子类一定可以出现。 LSP是继承复用的基石,只有当衍生类可以替换掉基类,软件单位的功能不受到影响时,基类才能真正被复用,而衍生类也能够在基类的基础上增加新的行为。里氏代换原则是对“开-闭”原则的补充。实现“开-闭”原则的关键步骤就是抽象化。而基类与子类的继承关系就是抽象化的具体实现,所以里氏代换原则是对实现抽象化的具体步骤的规范。

原则

第一点

子类必须实现父类的抽象方法,但不得重写(覆盖)父类的非抽象(已实现)方法。

class Foo {
    public void cal(int num1, int num2) {
        int value = num1 + num2;
        System.out.println("父类计算结果: " + value);
    }
}

class Son extends Foo {
    public void cal(int num1, int num2) {
        int value = num1 - num2;
        System.out.println("子类计算结果:" + value);
    }
}

class Cal{
    public static void main(String[] args) {
        Foo foo = new Foo();
        foo.cal(2,1);
        Son son = new Son();
        son.cal(2,1);
    }
}

在类的继承中,我们的父类定义好的方法,并不会强制要求其子类必须完全遵守该方法的实现规则。子类是可以修改它继承自父类的任意方法的。
在本例中,父类的本意是想要定义一个两数相加的方法,但是子类继承该方法后却修改为减法,并且也成功了。子类这样操作后,会对整个继承体系造成破坏。当你想把使用父类的地方替换为其子类时,会发现原来的正常的功能现在出现问题了。

第二点

当子类需要重载父类中的方法的时候,子类方法的形参(入参)要比父类方法输入的参数更宽松(范围更广)。

class Foo {
    public void method(List arrayList) {
        System.out.println("父类方法执行");
    }
}

class Son extends Foo {
    public void method(ArrayList list) {
        System.out.println("子类方法执行" );
    }
}

class Cal{
    public static void main(String[] args) {
        ArrayList list = new ArrayList();
        Foo foo = new Foo();
        Son son = new Son();
        System.out.println("使用父类对象调用的结果:");
        foo.method(list);
        System.out.println("将父类对象替换为子类对象调用结果");
        son.method(list);
    }
}

//输出
使用父类对象调用的结果:
父类方法执行
将父类对象替换为子类对象调用结果
子类方法执行

我们的本意是希望对象替换后还执行原来的方法的,可结果却发生变化了。

修改

class Foo {
    public void method(ArrayList arrayList) {
        System.out.println("父类方法执行");
    }
}

class Son extends Foo {
    //重载了父类的method,并且方法入参比父类的入仓范围更广
    public void method(List list) {
        System.out.println("子类方法执行" );
    }
}

第三点

重写或者实现父类方法的时候,方法的返回值可以被缩小,但是不能放大。

正例:

 class Foo {
    public List getList() {
        return new ArrayList();
    }
}

class Son extends Foo {
    public ArrayList getList() {
        return new ArrayList();
    }
}

反例:

class Foo {
    public ArrayList getList() {
        return new ArrayList();
    }
}

class Son extends Foo {
    public List getList() {
        return new ArrayList();
    }
}

如果我们试图在子类中放大,重写或实现来自父类方法的返回值时,代码会报错,连基本的编译器都无法通过。

第四点

子类可以拥有自己独特的方法或属性

class Foo {
    public void cal(int num1, int num2) {
        int value = num1 + num2;
        System.out.println("父类计算结果: " + value);
    }
}

class Son extends Foo {
    public void cal(int num1, int num2) {
        int value = num1 - num2;
        System.out.println("子类计算结果:" + value);
    }
    public void cal2(int num1, int num2) {
        int value = num1 + num2 +num2;
        System.out.println("子类计算结果:" + value);
    }
}

总结

通过上面的描述相信大家都对里氏替换原则有了一个基本的概念,其实它就是告诉我们在继承中需要注意什么问题和遵守什么规则。

然而在实际开发中我们在很多时候还是会违背该原则的,虽然表面上没有什么特别大的问题,但是这样做会大大增加代码的出错率。我们编写代码时不光要考虑怎么实现该功能,程序的健壮性和后期的扩展以及移植都是需要考虑到的。只有这样做才可以使我们的程序更加优秀。

标签:Foo,原则,里氏,int,子类,class,代换,父类,public
From: https://www.cnblogs.com/leepandar/p/16711324.html

相关文章

  • 设计模式---六大设计原则
    六大设计原则单一职责原则接口隔离原则开闭原则依赖倒置原则里氏代换原则迪米特法则单一职责原则我们分别看两个案例,一个是遵守单一职责原则,另一个是违背。违背......
  • OOP面向对象的七大设计原则
     一.开闭原则 OCP(Open-ClosedPrinciple)核心思想:对扩展开发,对修改关闭。好处:可以提高代码的可复用性。可以提高代码的可维护性。 二.里氏代换原则 LSP(LiskovSub......
  • 信息系统建设的原则
    为了能够适应开发的需要,在信息系统规划设计,以及系统开发的过程中,必须要遵守一系列原则,这是系统成功的必要条件。以下是信息系统开发常用的原则。1.高层管理人员介入原则一......
  • 改善界面设计方法的 3 个 UX 设计原则
    改善界面设计方法的3个UX设计原则我们谈用户体验和人机交互PhotoBy哈尔盖特伍德嘿朋友们,所以在年初,我在独立学习用户体验设计的同时还在大学学习了人机交互(HCI)......
  • 设计模式原则之“迪米特法则”
    一、是什么迪米特法则:也叫最少知识原则(LoD)如果两个类不必彼此直接通信,那么这两个类就不应当发生直接的相互作用如果其中一个类需要调用另一个类的某一个方法的话,可以通......
  • 面向对象的设计原则
    开闭原则(TheOpen-ClosedPrinciple,OCP)软件实体(模块,类,方法等)应该对扩展开放,对修改关闭。系统设计需要遵循开闭原则的原因稳定性。开闭原则要求扩展功能不修改原来的......
  • 软件测试的六大原则
    软件测试的原则是指帮助测试团队有效地利用他们的时间和精力来发现测试项目的隐藏bug的指导方针。从实践和研究中总结得出以下7条软件测试的基本原则,以便测试人员在软件......
  • 【校招VIP】[产品][一本][6分]简历原则上写一页
    关注【校招VIP】公众号,回复【简历】,添加校招顾问微信,即可获取简历指导!简历背景:21届一本产品简历评分:6分一、学员简历​​​ 二、指导意见:简历有两大块问题:1......
  • 里氏代换原则
    理论里氏代换原则:子类型必须能够替换掉它们的父类型。一个软件实体如果使用的是一个父类的话,那么一定适用于其子类,而且它察觉不出父类对象和子类对象的区别。也就是说,在......
  • 依赖倒转原则
    理论依赖倒转原则:A.高层模块不应该依赖低层模块。两个都应该依赖抽象B.抽象不应该依赖细节。细节应该依赖抽象依赖倒转可以说是面向对象设计的标志,用哪种语言来编写......