博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
设计模式-里氏替换原则
阅读量:6296 次
发布时间:2019-06-22

本文共 3170 字,大约阅读时间需要 10 分钟。

设计模式-里氏替换原则

优点

面向对象的语言继承必不可少的,有如下优点

  1. 代码共享,减少创建类的工作量
  2. 提高代码的重用性
  3. 提高代码的可扩展性
  4. 提高代码的可扩展性
  5. 提高产品代码的开放性
  6. 继承侵入性 只要继承,必须拥有父类的内容
  7. 降低代码的灵活性,子类必须拥有父类的属性和方法
  8. 增强耦合性。

提供规范

里氏替换原则,为继承定义规范。

长方形是不是正方形

正方形是一种特殊的长方形,如果将正方形设计为长方形的子类,不符合里氏替换原则

下方有三个类
类图如下
关系如上所示

package demo1;public class SmartTest {    /*     * 长方形的长增加超过宽     *      * @param r     * */        public void resize(Rectangle r) {        while (r.getHeight() <= r.getWidth()) {            r.setHeight(r.getHeight() + 1);        }    }}
package demo1;/* * 定义一个长方形类 * @author ming * */public class Rectangle {    protected long width;    // 可以访问基类继承而来的,不能访问基类本身的,对同包内的可见,并且子类也可见    protected long height;        public void setWidth(long width) {        this.width = width;    }        public long getWidth() {        return this.width;    }        public void setHeight(long height) {        this.height = height;    }        public long getHeight() {        return this.height;    }}
package demo1;/* * 定义一个正方形类继承自长方形类 *  * @author ming *  * */public class Square extends Rectangle{    public void setWidth(long width, long height) {        this.width = width;        this.height = height;    }        public long getWidth() {        return width;    }        public void setHeight(long height, long width) {        this.height = height;        this.width = width;    }        public long getHeight() {        return height;    }}

在上面的三块代码中,当调用SmartTest类的resize方法的时候,如果传入的是父类,那么将会可以的,如果传入的是子类,正方形,那么将会不可以的。

即。上方的为长方形行,正方形不行。
所以上面的栗子不符合里氏替换原则。
解决方法,使用继承时,要遵守里氏替换原则,类B继承类A时,不要重写父类A的方法,也不能重载父类A的方法。
如果代码更改如下更改
让其两个都共同定义同一个父类即可

其中最上层的类为两个类的抽象类。

改进如下

package com.ming;/* * 定义一个四边形类,只有get方法set方法 * @author ming * */public abstract class Quadrangle {    protected abstract long getWidth();    protected abstract long getHeight();}
package com.ming;public class Rectangle extends Quadrangle {    private long width;    private long height;        public void setWidth(long width) {        this.width = width;    }        public long getWidth() {        return this.width;    }        public void setHeight(long height) {        this.height = height;    }        public long getHeight() {        return this.height;    }}
package com.ming;public class Square extends Quadrangle{    private long width;    private long height;        public void setWidth(long width) {        this.height = width;        this.width = width;    }        public long getWidth() {        return this.,width;    }        public void setHeight(long height) {        this.height = height;        this.width = height;    }        public long getHeight() {        return this.height;    }}

在上方的图中,由于两个为平级关系,所以父类的地方,换成子类也都可以。

总结

里氏替换原则;父类可以的地方,换成子类也同样可以。

为什么要符合

一个栗子

package com.ming2;public class A {    public int func1(int a, int b) {        return a-b;    }}
package com.ming2;public class B extends A{    public int func1(int a, int b) {        return a+b;    }        public int func2(int a, int b) {        return func1(a,b)+100;    // 调用func1    }}

在上方中,如果这样书写

package com.ming2;public class Client {    public static void main(String[] args) {        B b = new B();        System.out.println(b.func1(100, 50));    }}

就违反了里氏替换原则,即子类能使用的时候,父类也必须能使用。

www.iming.info

转载地址:http://klvta.baihongyu.com/

你可能感兴趣的文章
springboot+logback日志异步数据库
查看>>
Typescript教程之函数
查看>>
Android 高效安全加载图片
查看>>
vue中数组变动不被监测问题
查看>>
3.31
查看>>
类对象定义 二
查看>>
收费视频网站Netflix:用户到底想要“点”什么?
查看>>
MacOS High Sierra 12 13系统转dmg格式
查看>>
关于再次查看已做的多选题状态逻辑问题
查看>>
动态下拉菜单,非hover
查看>>
政府安全资讯精选 2017年第十六期 工信部发布关于规范互联网信息服务使用域名的通知;俄罗斯拟建立备用DNS;Google打击安卓应用在未经同意情况下收集个人信...
查看>>
简单易懂的谈谈 javascript 中的继承
查看>>
iOS汇编基础(四)指针和macho文件
查看>>
Laravel 技巧锦集
查看>>
Android 使用 ViewPager+RecyclerView+SmartRefreshLayout 实现顶部图片下拉视差效果
查看>>
Flutter之基础Widget
查看>>
写给0-3岁产品经理的12封信(第08篇)——产品运营能力
查看>>
ArcGIS Engine 符号自动化配置工具实现
查看>>
小程序 · 跳转带参数写法,兼容url的出错
查看>>
flutter error
查看>>