前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >里式替换原则——面向对象程序设计原则

里式替换原则——面向对象程序设计原则

作者头像
海向
发布2019-11-05 16:37:14
4730
发布2019-11-05 16:37:14
举报
文章被收录于专栏:海向海向

目录

  • 定义
  • 意义
  • 做法
  • 实践
    • uml图
    • 代码部分

github仓库

定义

Liskov于1987年提出了一个关于继承的原则“Inheritance should ensure that any property proved about supertype objects also holds for subtype objects.”—— 继承必须确保超类所拥有的性质在子类中仍然成立.。通俗的来讲就是子类可以扩展父类的功能,但是不能改变父类原有的功能。

该原则称为Liskov Substitution Principle——里氏替换原则。

里氏替换原则主要阐述了有关继承的一些原则,也就是什么时候应该使用继承,什么时候不应该使用继承,以及其中蕴含的原理。里氏替换原是继承复用的基础,它反映了基类与子类之间的关系,是对开闭原则的补充,是对实现抽象化的具体步骤的规范。

意义

  1. 防止重写父类方法,出现父类复用性差的情况。
  2. 程序运行正确性的保证,即类的扩展不会给系统带来新的错误,降低了出错的可能性。因为子类重写了父类方法,在使用多态特性时,程序可能会出现不可预知的错误。

做法

  • 子类可以实现父类的抽象方法,但不能覆盖父类的非抽象方法。
  • 子类中可以增加自己特有的方法。
  • 当子类的方法重载父类的方法时,方法的前置条件(即方法的形参)要比父类方法的输入参数更宽松。
  • 当子类的方法实现父类的抽象方法时,方法的后置条件(即方法的返回值)要比父类更严格。

实践

在英雄联盟中,每个英雄到了6级都会拥有大招,大招的效果随着英雄等级提升而提升,盲僧的大招有伤害,杰斯的大招只是切换形态,没有伤害。我们在杰斯类中覆盖了父类的方法,导致调用getrDPS()方法出现了意料之外的错误。

(后话系列)对于这种情况我们应该将Hero再细分为两种子类,一种是大招有伤害类型,一种是无伤害类型,LeeSin和Jess分别继承他们,将Hero做成顶级类,只拥有管理等级的功能。

uml图

代码部分

英雄基类

代码语言:javascript
复制
/**
 * 英雄基类
 */
public class Hero {
    /** R 技能伤害 */
    private double rDPS;

    /** 英雄等级 */
    private int clas;

    public void setClas(int clas){
        this.clas = clas;
    }

    /**
     * R技能伴随等级的变化
     */
    public void getrDPS(){
        rDPS = 2100 / clas * 3.97;
        System.out.println("R技能的伤害为" + rDPS);
    }
}

盲僧

代码语言:javascript
复制
/**
 * 盲僧
 */
public class LeeSin extends Hero{}

杰斯

代码语言:javascript
复制
/**
 * 杰斯
 */
public class Jess extends Hero{
    @Override
    public void setClas(int clas) {
        System.out.println("虽然我到6了,但咱大招么得伤害呀,就不用传值等级了,反正也没用");
    }
}

测试类

代码语言:javascript
复制
public class Main {
    public static void main(String[] args) {
        Hero leeSin = new LeeSin();
        leeSin.setClas(6);
        leeSin.getrDPS();

        Hero jess = new Jess();
        jess.setClas(6);
        jess.getrDPS();
    }
}

因为杰斯大招没伤害,重写了父类的setClas(int clas)方法没有为clas赋值,故而在计算R技能伤害时发生了除零异常。

代码语言:javascript
复制
R技能的伤害为1389.5
虽然我到6了,但咱大招么得伤害呀,就不用传值等级了,反正也没用
Exception in thread "main" java.lang.ArithmeticException: / by zero
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-11-04 ,如有侵权请联系 cloudcommunity@tencent.com 删除

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

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 定义
  • 意义
  • 做法
  • 实践
    • uml图
      • 代码部分
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档