在复习过程中,LSP原则是个很重要的内容。这里先给出LSP原则的定义。

LSP定义
Functions that use pointers or referrnces to base classes must be able to use objects of derived classes without knowing
it.(所有引用基类的地方必须能透明地使用其子类的对象。)

这个的主要作用就是规范继承时子类的一些书写规则。其主要目的就是保持父类方法不被覆盖。

也就是所有引用父类的地方,替换子类进去,不会有任何影响。

子类必须完全实现父类的方法
子类可以有自己的个性
覆盖或实现父类的方法时输入参数可以被放大
覆盖或实现父类的方法时输出结果可以被缩小

LSP是子类型关系的一个特殊定义,称为(强)行为子类型化。在编程语言中,LSP依赖于以下限制:
前置条件不能强化
后置条件不能弱化
不变量要保持或增强
子类型方法参数:逆变
子类型方法的返回值:协变
异常类型:协变

这里出现了两个生词:协变和逆变。本篇文章主要说一下这俩是啥。

逆变与协变综述:如果A、B表示类型,f(⋅)表示类型转换,≤表示继承关系(比如,A≤B表示A是由B派生出来的子类):

f(⋅)是逆变(contravariant)的,当A≤B时有f(B)≤f(A)成立;
f(⋅)是协变(covariant)的,当A≤B时有f(A)≤f(B)成立;
f(⋅)是不变(invariant)的,当A≤B时上述两个式子均不成立,即f(A)与f(B)相互之间没有继承关系。

协变(Co-variance)
  父类型->子类型:越来越具体(specific)。
  在LSP中,返回值和异常的类型:不变或变得更具体 。

逆变(Contra-variance)

  父类型->子类型:越来越抽象。

  参数类型:要相反的变化,不变或越来越抽象。

来看一下应用:

数组是协变的:一个数组A[ ] ,可能包含了A类型的实例或者A的任何子类型的实例

1 Number[] numbers = new Number[2];
2 numbers[0] = new Integer(10);
3 numbers[1] = new Double(3.14);
4
5 Integer[] myInts = {1,2,3,4};
6 Number[] myNumber = myInts;
7
8 myNumber[0] = 3.14; //run-time error!

第8行会报错的原因是myNumber指向的是一个Integer[] 而不是Number[],对Interger赋值一个double类型的,不是协变

其实在继承中只需要注意LSP原则即可,这是不矛盾的。

对于参数,也就是前置条件,应当逆变,把前置条件范围放宽。

对于返回值,也就是后置条件,应当协变,把后置条件范围缩小。

这两者加起来,也就是规约变强,符合LSP。

最新文章

  1. jQuery 获取当前节点的html包含当前节点的方法
  2. [转载] COM 套间
  3. KlayGE 4.4中渲染的改进(四):SSSSS
  4. Bootstrap 4 中 Alerts 实现
  5. UIButton的遍历
  6. Java抽象类和抽象方法例子
  7. P1832 A+B Problem(再升级)
  8. 《神经网络和深度学习》系列文章十二:Hadamard积,s⊙t
  9. ASP.NET Core和ASP.NET Framework共享Identity身份验证
  10. Farming
  11. spring mvc 的基本注解
  12. Caffe代码分析--crop_layer.cu
  13. OpenCV学习1-----打开摄像头并在画面上添加水印
  14. Spark 1.6升级2.x防踩坑指南
  15. luogu5290 春节十二响
  16. JAVA基础复习与总结<二>构造方法_static关键字_final关键字
  17. Wpf ViewModel中 ObservableCollection不支持从调度程序线程以外的线程对其 SourceCollection 进行的更改
  18. 【清北学堂2018-刷题冲刺】Contest 5
  19. Asp.net Core认证和授权:Cookie认证
  20. kubernetes 中,Pod、Deployment、ReplicaSet、Service 之间关系分析

热门文章

  1. 调度器42—进程exit退出流程
  2. html入門 如何 區別行級元素 和 塊級元素
  3. CCCC L3-032 关于深度优先搜索和逆序对的题应该不会很难吧这件事 【树状数组】
  4. 关于新手在使用git过程中的基本问题--前端开发篇
  5. Android组件化开发-----页面路由(ARouter)
  6. c++ 引用 指针。
  7. 什么是axios
  8. 多线程事务回滚sqlSession, spring-mybatis 开启事务
  9. ONOS中新建分支并关联远程库
  10. 通过if 简单判断奇数偶数