前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >java设计模式3,里氏替换原则

java设计模式3,里氏替换原则

作者头像
全栈程序员站长
发布2022-11-18 17:48:49
发布2022-11-18 17:48:49
68400
代码可运行
举报
运行总次数:0
代码可运行

大家好,又见面了,我是你们的朋友全栈君。

一、里氏替换原则定义

在面向对象的程序设计中,里氏替换原则(Liskov Substitution principle)是对子类型的特别定义。它由芭芭拉·利斯科夫(Barbara Liskov)在1987年在一次会议上名为“数据的抽象与层次”的演说中首先提出。 里氏替换原则的内容可以描述为: “派生类(子类)对象可以在程序中代替其基类(超类)对象。” 以上内容并非利斯科夫的原文,而是译自罗伯特·马丁(Robert Martin)对原文的解读。 芭芭拉·利斯科夫与周以真(Jeannette Wing)在1994年发表论文并提出以上的Liskov代换原则。

简单来说,子类可以扩展父类的功能,但不能改变父类原有的功能,也就是说,在子类继承父类时,除添加新的方法且完成新增功能外,尽量不要重写父类的方法。

二、里氏替换原则的作用

  1. 里氏替换原则是实现开闭原则的重要方式之一;
  2. 解决了继承中重写父类造成的可复用性变差的问题;
  3. 是动作正确性的保证,即类的扩展不会给已有的系统引入新的错误,降低了出错的可能性。
  4. 加强程序的健壮性,同时变更时可以做到非常好的兼容性,提高程序的维护性、可扩展性、降低需求变更时引入的风险;

三、违背原则场景

灵珠和魔丸本是一体,被元始天尊提炼了出来,灵珠将为人民服务,魔丸则会危害世界,所以元始天尊将这个艰巨的任务交给太乙真人,让灵珠投胎到“根正苗红”的李靖家,魔丸动用天劫咒,三年后摧毁。 可是阴差阳错,灵珠被调包,本来可以为民除害的哪吒成了魔,而魔族敖丙出身却成了服务人民的苗子。

代码语言:javascript
代码运行次数:0
运行
复制
package com.guor.principle.animals;

public class Nezha { 
   

    /** * 名号 */
    public void nickName(){ 
   
        System.out.println("八臂哪吒");
    }

    /** * 师傅 */
    public void master(){ 
   
        System.out.println("太乙真人");
    }

    /** * 混元珠 */
    public void MixedYuanzhu(){ 
   
        System.out.println("魔丸");
    }
}

既然功能相同,敖丙继承哪吒,就可以了。

代码语言:javascript
代码运行次数:0
运行
复制
package com.guor.principle.animals;
public class Aobing extends Nezha{ 

/** * 名号 */
public void nickName(){ 

System.out.println("三太子");
}
/** * 师傅 */
public void master(){ 

System.out.println("申公豹");
}
/** * 混元珠 */
public void MixedYuanzhu(){ 

System.out.println("灵珠");
}
}

敖丙继承哪吒之后,进行方法重写。

这种继承父类的优点是复用了父类的核心功能逻辑,但是也破坏了原有的方法,此时也破坏了原有的方法。此时继承父类实现的敖丙并不满足里氏替换原则,也就是说,此时的子类不能承担原父类的功能,直接给哪吒用,因为称号、师傅、混元珠也都也不一样嘛。

四、里氏替换原则改变代码

哪吒和敖丙都有称号、师傅、混元珠,在《封神榜》中也有很多共同特点和经历,实现这样的类的最好方式是提取出一个抽象类,由抽象类定义所有人物的共同核心属性、逻辑。

1、抽象人物类

在抽象类银行卡类中,提供了人物的基本信息,包括id、姓名,姓名、武力值以及三个基本的方法。接下来继承这个实现类,实现哪吒和敖丙的技能逻辑。

代码语言:javascript
代码运行次数:0
运行
复制
package com.guor.principle;
public abstract class Hero { 

// 编号
private String id;
// 姓名
private String name;
// 武力值
private Integer forceValue;
/** * 名号 */
public void nickName(){ 

System.out.println("英雄名号");
}
/** * 师傅 */
public void master(){ 

System.out.println("师傅");
}
/** * 混元珠 */
public void MixedYuanzhu(){ 

System.out.println("混元珠");
}
}

2、哪吒子类

哪吒类继承了英雄父类Hero,实现的核心功能包括名号、师傅、混元珠,拓展了新的方法重大事件。

代码语言:javascript
代码运行次数:0
运行
复制
package com.guor.principle;
public class Nezha extends Hero { 

public Nezha(String id, String name, Integer forceValue) { 

super(id, name, forceValue);
}
/** * 名号 */
public void nickName(){ 

System.out.println("八臂哪吒");
}
/** * 师傅 */
public void master(){ 

System.out.println("太乙真人");
}
/** * 混元珠 */
public void MixedYuanzhu(){ 

System.out.println("魔丸");
}
/** * 重大事件 */
public void event(){ 

System.out.println("哪吒闹海");
}
}

3、敖丙子类

敖丙类继承了英雄父类Hero,实现的核心功能包括名号、师傅、混元珠,拓展了新的方法虾兵蟹将。

代码语言:javascript
代码运行次数:0
运行
复制
package com.guor.principle;
public class Aobing extends Hero { 

public Aobing(String id, String name, Integer forceValue) { 

super(id, name, forceValue);
}
/** * 名号 */
public void nickName(){ 

System.out.println("三太子");
}
/** * 师傅 */
public void master(){ 

System.out.println("申公豹");
}
/** * 混元珠 */
public void MixedYuanzhu(){ 

System.out.println("灵珠");
}
/** * 手下 */
public void subordinate(){ 

System.out.println("虾兵蟹将");
}
}

以上的实现方法都是在遵循里氏替换原则下完成的,子类随时可以替换英雄类。

继承作为面向对象的重要特性,虽然给程序开发带来了非常大的便利,但也引入了一些弊端。继承的开发方式会给代码带来侵入性,可移植能力降低,类之间的耦合度较高。当对父类修改时,就要考虑一整套子类的实现是否有风险,测试成本较高。

里氏替换原则的目的是使用约定的方式,让使用继承后的代码具备良好的扩展性和兼容性。

在日常开发中使用继承的地方并不多,在有些公司的代码规范中也不会允许许多层继承,尤其是一些核心服务的扩展。而继承多数使用在系统架构初期定义好的逻辑上或抽象出的核心功能里。如果使用了继承,就一定要遵从里氏替换原则,否则会让代码出现问题的概率变大。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/222875.html原文链接:https://javaforall.cn

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022年10月29日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、里氏替换原则定义
  • 二、里氏替换原则的作用
  • 三、违背原则场景
  • 四、里氏替换原则改变代码
    • 1、抽象人物类
    • 2、哪吒子类
    • 3、敖丙子类
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档