zoukankan      html  css  js  c++  java
  • Java泛型学习笔记

    在学习继承的时候, 我们已经知道可以将一个子类的对象赋值给其父类的对象, 也就是父类引用指向子类对象, 如:

    1 Object obj = new Integer(10);

    这其实就是面向对象编程中的is-a关系. 既然上面的代码正确, 那么在泛型中, 也可以使用如下代码:

     1 public class Box<T> {
     2     private T obj;
     3     
     4     public Box() {}
     5 
     6     public T getObj() {
     7         return obj;
     8     }
     9 
    10     public void setObj(T obj) {
    11         this.obj = obj;
    12     }
    13 
    14     public Box(T obj) {
    15         super();
    16         this.obj = obj;
    17     }
    18 }

    调用:

    1 Box<Number> b = new Box<>();
    2 Integer i = 10;
    3 Double d = 2.3;
    4 b.setObj(i);
    5 System.out.println(b.getObj());
    6 b.setObj(d);
    7 System.out.println(b.getObj());

    这是正确的, 因为10, 2.3的类型都是Number的子类. 但是, 假设我们有如下方法:

    1 public static void print(Box<Number> b) {
    2     System.out.println(b.getObj());
    3 }

    然后我们调用:

    1 Box<Number> b1 = new Box<>();
    2 Integer i = 10;
    3 b1.setObj(i);
    4 print(b1);

    以上的程序也是能够正常运行的, 但是如果我们改用如下的方式来调用:

    1 Box<Integer> b2 = new Box<>();
    2 b2.setObj(10);
    3 print(b2); // 编译失败

    这就不会通过编译. 因为, 无论Integer和Number的关系如何, Box<Integer>和Box<Number>是没有关系的, 他们之间唯一的关系就是他们都是Object的子类. 如图所示:

    (如果想要让他们也拥有继承关系, 请参看我的下一篇博文《浅析泛型中通配符的使用》)

    那么泛型类之间拥有继承(或实现接口)关系是怎样的呢? 我们以List和ArrayList为例:
    通过查看API文档, 我们可以发现ArrayList类是这样的:

    1 public class ArrayList<E>extends AbstractList<E>implements List<E>, RandomAccess, Cloneable, Serializable

    而List接口又是:

    1 public interface List<E>extends Collection<E>

    这时, 我们就可以说ArrayList<String>实现了List<String>接口继承了Collection<String>接口, 相信这样的例子我们已经见的不少了:

    1 List<String> list = new ArrayList<String>();

    我们也可以自己定义具有继承关的泛型, 下面是一个继承了List接口的泛型接口:

    1 interface PayloadList<E,P> extends List<E> {
    2   void setPayload(int index, P val);
    3   ...
    4 }

    如果我们有如下的类实现该接口:

    1 PayloadList<String,String>
    2 PayloadList<String,Integer>
    3 PayloadList<String,Exception>

    那么他们之间的关系就如图所示:

    总结: 两个类(甚至是同一个类)的泛型所具有继承(或实现)关系并不能代表这两个类之间的关系. 除非这两个类是有着明确的继承(或实现关系), 其泛型间的关系并不能对其造成影响.

     References:

    https://docs.oracle.com/javase/tutorial/java/generics/inheritance.html

  • 相关阅读:
    free pascal dialect
    free pascal
    free pascal
    跳槽后在新公司的一点感悟
    安全攻防技能30讲
    设计模式之美(二)——设计模式
    设计模式之美(一)——设计原则、规范与重构
    数据结构和算法躬行记(8)——动态规划
    倾斜摄影实景三维在智慧工厂 Web 3D GIS 数字孪生应用
    智慧文旅促进旅游业发展,可视化带你云游武夷
  • 原文地址:https://www.cnblogs.com/zhenyu-go/p/5536664.html
Copyright © 2011-2022 走看看