zoukankan      html  css  js  c++  java
  • Java的协变(extends)和逆变(super),说白了都是子类的实例赋值给父类的变量

    总的来说,协变和逆变   都是  子类的实例赋值给父类的变量。

    为啥呢, 你要想把父类的实例赋值给子类的变量,那是要报错的

    PECS (Producer Extends,Consumer Super)

    当客户端是producer,就意味着客户端生成的数据插入你的集合中,你的参数是父类,客户端的数据是子类,所以用extends

    当客户端是consumer,就意味着客户端从你的集合里面取数据,你的参数是子类,客户端的数据是父类,所以用super

    如下代码: java.util.Collections的copy方法(JDK1.7) 

    src, 顾名思义,就是源数据, copy方法要从src中取数据,所以用extends

    desc,就是目标数据,copy方法把数据插到desc中,所以用super。

    为啥呢?

    假设 T 是copy方法中使用的类型。

    src的类型我们就叫  input,  input extends T,所以input就是T的子类,

    desc的类型我们就叫output,   output super T, 所以output就是T的父类。

    所以 input就是output的子类。

     那么copy中的 di 就是ListIterator<Output>,    si 就是ListIterator<Input>

    di.set(si.next());    这句话就是把 input 赋值给output。  说白了,就是把 子类的实例赋值给父类的变量。

    协变是从 input到  T,  就是从调用方给你的方法数据。  调用方就是数据的产生者。用extends

    逆变是从 T 到 output, 就是你的方法给调用方数据。 调用方就是数据的消费者。用super

    重要:要注意T的位置,

    <? extends T>      ,                T在extends的右边, T是父类,    ?是子类。  ?才是真实的类型, 接收变量的类型是T

    <T extends BaseClass>  ,   T在extends的左边, T是子类。 T是真实的类型,接收变量的类型是  BaseClass

    <? super T>   ,                    T在super的右边,  T是子类 ,   ?是父类。  ?才是真实的类型,接收变量的类型是?

    <T super BaseClass>   ,       T在super的左边,  T是父类。     T是真实的类型,接收变量的类型是T

  • 相关阅读:
    git merge远程合并
    开发中必知必会的常用Linux命令
    mysql双机双向热备
    入门级实操教程!从概念到部署,全方位了解K8S Ingress!
    linux常用命令,你应该了解的Linux知识
    MFC的静态库.lib、动态库.dll(包含引入库.lib)以及Unicode库示例
    Java 表达式之谜:为什么 index 增加了两次?
    Vavr Option:Java Optional 的另一个选项
    一文详解 Java 的八大基本类型!
    如何找到真正的 public 方法
  • 原文地址:https://www.cnblogs.com/yfdream/p/7878764.html
Copyright © 2011-2022 走看看