Liskov可替换原则(LSP)

Behavioral subtyping(行为子类型)

如果B是A的子类型,则有两条隐含语义:
1.任意的B都是A;
2.A能做的事,B也都能做;
如果满足这两条,则称B为A的行为子类型。

行为子类型形式化的定义:
1.父类型的特征,子类型也有;
2.父类型能做的事,子类型也能做,并且子类型不能比父类型做得更差;
3.父类型不能做的事,子类型可能能做。

这两个对行为子类型的定义是等价的。

行为子类型能够满足子类型多态的要求,既客户端可以用统一的方式处理不同类型的对象。

Liskov可替换原则(LSP)

1.子类型能增加方法,都是不能删除父类中的方法;
2.子类型需要实现抽象类型中的所有未实现的方法;
3.子类型中重写的方法的返回值类型必须与父类型方法的返回值类型相同,或者是父类型方法的返回值类型的协变;
4.子类型中重写的方法的参数类型必须使用与父类型方法相同参数类型,或者是父类型方法的参数类型的反协变;
5.子类型中重写的方法不能抛出额外的异常;
6.子类型的RI应该不变或者比父类型的RI更强;
7.子类型的前置条件应该不变,或者比父类型的前置条件更弱;
8.子类型的后置条件应该不变,或者比父类型的后置条件更强。

前面5个条件编译器可以自动检测,不过后面的三个条件,是跟RI和spec有关的,编译器是无法检测的,需要程序员自己检测。

解释

类包括属性和方法两个部分。
对于属性而言:
子类的RI不能破坏父类的RI,因此子类的RI需要跟父类一样,或者比父类更强。

对于方法而言:
1.父类能做的事,子类也要能做。因此父类有的方法,子类也要有,子类不能减少父类中的方法,并且子类型需要实现抽象类型中的所有未实现的方法;
2.对于父类中已有的方法,子类要跟父类一样,或者比父类做的更好;
子类可以通过重写来实现做的更好:
在参数层面,意味着子类方法要比父类接受参数的范围更广,能够处理更多的数据。因此,子类型中重写的方法的参数类型是父类型方法的参数类型的反协变,既有更弱的前置条件;
在返回值层面,意味着子类方法得到的结果要比父类得到的结果更加具体精确。因此,子类型中重写的方法的返回值类型是父类型方法的返回值类型的协变,既有更强的后置条件;
在异常层面,异常代表程序处理不了的情况,因此,父类能够处理的异常,子类应该也能处理,或者处理的更好,而父类不能处理的异常,子类可以是能够处理的,或者抛出与父类异常一样的异常,或者抛出父类异常的子类,代表着描述错误的信息更加具体。因此,子类型中重写的方法不能抛出额外的异常;

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值