软件构造第五章

java子类型多态

三种多态:

多态性是指为不同类型的实体提供一个接口,或者使 用一个符号来表示多个不同的类型。

  • 一个函数可以有多个同名的实现(方法重载)
  • 一个类型名字可 以代表多个类型(泛型编程)
  • 一个变量名字可以代表多个类的实例(子类型)

子类型的Liskov Substitution Principle (LSP)原则

  • 子类型可以添加,但不能删除方法
  • 具体类必须实现所有未定义的方法
  • 重写方法必须返回相同的类型或子类型
  • 重写方法必须接受相同的参数类型
  • 覆盖方法可能不会引发其他异常
    也可以写成
  • 相同或更强的不变量RI
  • 所有方法的相同或更强的后置条件
  • 所有方法的相同或较弱的前提条件

型变(这里说的不是java,只是三种型变类型)

  • 协变:A是B的子类,则A中的参数也是B中参数的子类
  • 逆变:A是B的子类,则A中的参数是B中参数的父类
  • 不变:A是B的子类,则A中的参数与B中参数类型一致

泛型

  • 虚拟机中没有泛型类型对象-所有对 象都属于普通类!泛 型信息只存在于编译阶段,在运行时会被”擦除” 。类型变量会被擦除,替换为限定类型,如果没 有限定类型则为Object类型。所以运行时类型查询 只适用于原始类型,不适用于泛型,下面是两个例子
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
  • Java中的泛型是不“型变”的。

已知Number类型是Integer的父类。可以知道Number[]类型是Integer[]的父类,但是List<Integer>不是List<Number>的子类。原因就是List是泛型,而泛型不“型变”。

通配符:?

List<?> 或 List<? extends Animal> 或List<? super Animal>,其中Animal是一个自定义的类。
通配符可以视作协变。若Cat作为Animal的子类,WhiteCat的父类,则List<Cat>是List<? extends Animal> 的子类,是List<? super WhiteCat>的父类。现在以Animal(爹)、Cat(子)、WhiteCat (孙子)为例大致说一下注意点:

  • List<? extends Animal>:List<Cat>与List<WhiteCat>都可以是它的子类。它可以调用get方法,但是不能调用增加(add)或者改变(set)的方法
    – 调用一个返回Animal类型(或子类型)的方法(如 :T get(int pos))是安全的, 因为compiler知道这个List中的任何对象至少具有 Animal类型(或子类型),可以完成类型转换。
    – 但调用类似add(E e)的方法则不安全,类型擦除机制会导致运行时可以往animals中储存 各种类型的对象。 所以就直接不让加入了。
  • List<? super Cat>:List<Animal> 是它的子类。
    – 调用add等方法的时候,可以加入Cat或其子类;
    – 调用get方法时候,得到的东西必须强转。由于不知道里面是什么,强转不安全,因此不要随便用

注意,? extends Animal不是一个类,只能用于泛型中(我学过的地方只能这么做)

说点什么

前几天学了一点关于子类的东西,今天又看了一些。主要学习了通配符的使用以及LSP规则。关于通配符中List<? super Cat>的理解以前一直有错误。以为不能使用get方法,后来发现不是这个意思,是get之后返回了一个Object的类型(我是这么理解的。应该是类型擦除成什么样返回什么),只有使用强转才能变为想要的类型。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值