关于里氏替换原则与多态概念纠正

public abstract class Quadrangle{
protected abstract void getWidth();
protected abstract void getHeight();
}
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.designphilsophy.lsp.version2;

/**
 * 自己声明height和width
 * @author xingjiarong
 *
 */
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 width;
    }

    public void setHeight(long height) {
        this.height = height;
        this.width = height;
    }

    public long getHeight() {
        return height;
    }
}

想必谈到设计模式,不可避免要扯一扯的便是这著名的六大原则。

其中最为重要也常有初学者心怀疑虑的就是今天要说得里氏替换原则。

首先,先说说这究竟是个什么概念。

里氏,是一个姓里的外国人,这原则就是他提出的。

里氏替换原则(LSP)的定义:所有父类存在的地方都能透明的使用其子类的对象。里氏替换原则告诉我们,在软件中将一个基类对象替换成它的子类对象,程序不会产生任何错误,如果一个软件实体使用的是一个子类对象的话,那么它不一定能够使用基类对象。里氏替换原则是实现开闭原则的重要方式之一,由于使用基类对象的地方都可以使用子类对象,因此在程序中尽量使用基类类型来对对象进行定义,而在运行时再确定其子类类型,用子类对象来替换父类对象。


##里氏替换原则为良好的继承定义了一个规范,它包含了4层定义:


子类必须完全实现父类的方法。
子类可以有自己的个性。
覆盖或实现父类的方法时输入参数可以被放大。
覆写或实现父类的方法时输出结果可以被缩小。
采用里氏替换原则的目的就是增强程序的健壮性,版本升级时也可以保持非常好的兼容性。即使增加子类,原有的子类还可以继续运行。在实际项目中,每个子类对应不同的业务含义,使用父类作为参数,传递不同的子类完成不同的业务逻辑,非常完美。

看到一句话,白马是马,而马非白马。

这位仁兄的博客写得也真是有意思了。贴个连接方便以后温习。点击打开链接

里面提到,正方形不可以是正方形的子类,举例深明,浅显易懂。

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.designphilsophy.lsp.version2;

/**
 * 自己声明height和width
 * @author xingjiarong
 *
 */
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 width;
    }

    public void setHeight(long height) {
        this.height = height;
        this.width = height;
    }

    public long getHeight() {
        return height;
    }
}

此时调用smart,显然正方形的情况出现了bug,会一直long下去。

今日做笔记的时候,顺带一搜还真有个知乎相关的问题。是这么说的:微笑

JAVA中,多态是不是违背了里氏替换原则??

里氏替换原则要求子类避免重写父类方法,而多态的条件之一却是要求子类重写父类的方法。所以,我搞不懂里氏替换原则与继承,多态之间的关系。这是问题
这是某位古道热肠的程序猿给的回答,居然关心起机器人的生娃问题,这么一想,这个原则还真是颇有哲学气息,竟涵盖了诡辩,数学,电子技术(计算机编程)各个方面,实在是重要的很啊。




没有更多推荐了,返回首页