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

  • 相关阅读:
    合理处理沉没成本
    推荐一个基于Ajax的查询API网站
    为blog添加天气预报功能
    我仅仅一个熟练的coder
    管理和IT的对话
    10个你未必知道的CSS技巧
    如何使用ajax开发web应用程序(二)
    5月20日,系分考试后感。
    说说大型高并发高负载网站的系统架构
    盗用sina的爱问投诉代码实现网页对话框。
  • 原文地址:https://www.cnblogs.com/yfdream/p/7878764.html
Copyright © 2011-2022 走看看