Java设计原则(六)里氏替换原则

里氏替换原则

定义

		如果对每一个类型T1的对象o1,都有类型为T2的对象o2,
使得以T1定义的所有程序P在所有的对象o1都替换成o2时,程序P的
行为没有发生变化,那么类型T2是类型T1的子类型。

定义扩展

		一个软件实体如果都使用一个父类的话,那一个定使用其子类,
	所有引用父类的地方必须能透明地使用其子类的对象,子类对象能
	替换父类对象,而程序逻辑不变。

引申意义

子类可以扩展父类的功能,但不能改变父类的原有功能。

含义1

子类可以实现父类的抽象方法,但不能覆盖父类的非抽象方法。

含义2

子类可以增加自己特有的方法

含义3

当子类的方法重载父类的方法时,方法的前置条件(方法的输入,入参)
要比父类的输入方法更宽松

含义4

当子类的方法实现父类的方法时(重写,重载或实现抽象方法),
方法的后置条件(方法的输出,返回值)要比父类的更严格或相等

优点

1. 约束继承泛滥,是开闭原则的一种体现。
2. 加强程序的健壮性,同时变更时也可以做到非常好的兼容性,提高
程序的维护性,扩展性。降低需求变更时引入的风险。

代码演示

在演示开闭原则的代码中,就很好的遵守了里氏替换原则,
下面使用另外一段代码演示里氏替换原则:

public class Rectangle {

    private long height;

    private long weight;

    public long getHeight() {
        return height;
    }

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

    public long getWeight() {
        return weight;
    }

    public void setWeight(long weight) {
        this.weight = weight;
    }
}

public class Square extends Rectangle{

    private long length;

    public long getLength() {
        return length;
    }

    public void setLength(long length) {
        this.length = length;
    }

    @Override
    public long getHeight() {
        return getLength();
    }

    @Override
    public void setHeight(long height) {
        setLength(height);
    }

    @Override
    public long getWeight() {
        return getLength();
    }

    @Override
    public void setWeight(long weight) {
       setLength(weight);
    }
}


//test1
public class SimpleTest {

    public static void main(String[] args) {
        Rectangle rectangle = new Rectangle();
        rectangle.setHeight(18);
        rectangle.setWeight(20);
        resize(rectangle);
    }

    private static void resize(Rectangle rectangle) {
        while (rectangle.getWeight() >= rectangle.getHeight()) {
            rectangle.setHeight(rectangle.getHeight() + 1);
            System.out.println("weight:" + rectangle.getWeight() + ",height:" + rectangle.getHeight());
        }
        System.out.println("Resize end, weight:" + rectangle.getWeight() + ",height:" + rectangle.getHeight());
    }
}

//test2
public class SimpleTest {

    public static void main(String[] args) {

        Square square = new Square();
        square.setLength(20);
        resize(square);
    }

    private static void resize(Rectangle rectangle) {
        while (rectangle.getWeight() >= rectangle.getHeight()) {
            rectangle.setHeight(rectangle.getHeight() + 1);
            System.out.println("weight:" + rectangle.getWeight() + ",height:" + rectangle.getHeight());
        }
        System.out.println("Resize end, weight:" + rectangle.getWeight() + ",height:" + rectangle.getHeight());
    }
}

在代码中,test1的测试结果是:

weight:20,height:19
weight:20,height:20
weight:20,height:21
Resize end, weight:20,height:21

test2的测试结果是:(截取了一段,方法执行了一个死循环)

weight:4599496,height:4599496
weight:4599497,height:4599497
weight:4599498,height:4599498
weight:4599499,height:4599499
weight:4599500,height:4599500

显然该代码不符合里氏替换原则:因为在Square在继承了Rectangle的时候重写了父类中的非抽象方法,违反了含义1:子类可以实现父类的抽象方法,但不能覆盖父类的非抽象方法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值