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

 Object obj = new Integer(10);

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

 public class Box<T> {
private T obj; public Box() {} public T getObj() {
return obj;
} public void setObj(T obj) {
this.obj = obj;
} public Box(T obj) {
super();
this.obj = obj;
}
}

调用:

 Box<Number> b = new Box<>();
Integer i = 10;
Double d = 2.3;
b.setObj(i);
System.out.println(b.getObj());
b.setObj(d);
System.out.println(b.getObj());

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

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

然后我们调用:

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

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

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

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

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

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

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

而List接口又是:

 public interface List<E>extends Collection<E>

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

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

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

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

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

 PayloadList<String,String>
PayloadList<String,Integer>
PayloadList<String,Exception>

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

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

References:

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

Java泛型学习笔记 - (六)泛型的继承的更多相关文章

  1. Java IO学习笔记六:NIO到多路复用

    作者:Grey 原文地址:Java IO学习笔记六:NIO到多路复用 虽然NIO性能上比BIO要好,参考:Java IO学习笔记五:BIO到NIO 但是NIO也有问题,NIO服务端的示例代码中往往会包 ...

  2. Java泛型学习笔记 - (一)泛型的介绍

    一.什么是泛型:泛型的作用是用来规定一个类, 接口或方法所能接受的数据的类型. 就像在声明方法时指定参数一样, 我们在声明一个类, 接口或方法时, 也可以指定其"类型参数", 也就 ...

  3. java基础学习笔记六(继承)

    继承的概念 继承是java面向对象编程技术的一块基石,因为它允许创建分等级层次的类. 继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父 ...

  4. java jvm学习笔记六(实现写自己的安全管理器)

    安全管理器SecurityManager里设计的内容实在是非常的庞大,它的核心方法就是checkPerssiom这个方法里又调用AccessController的checkPerssiom方法,访问控 ...

  5. Java IO学习笔记六

    打印流 在整个IO包中,打印流是输出信息最方便的类,主要包含字节打印流(PrintStream)和字符打印流(PrintWrite).打印流提供了非常方便的打印功能,可以打印任何的数据类型,例如:小数 ...

  6. 《Thinking in Java》学习笔记(六)

    1.Class相关知识 Class类可以理解为类的图纸,通过Class类可以分析类的结构.构建出类的实例. Class.forName("test.TestClass").newI ...

  7. Java基础学习笔记六 Java基础语法之类和ArrayList

    引用数据类型 引用数据类型分类,提到引用数据类型(类),其实我们对它并不陌生,如使用过的Scanner类.Random类.我们可以把类的类型为两种: 第一种,Java为我们提供好的类,如Scanner ...

  8. Android(java)学习笔记118:类继承的注意事项

    /* 继承的注意事项: A:子类只能继承父类所有非私有的成员(成员方法和成员变量) B:子类不能继承父类的构造方法,但是可以通过super(马上讲)关键字去访问父类构造方法. C:不要为了部分功能而去 ...

  9. Java NIO学习笔记六 SocketChannel 和 ServerSocketChannel

    Java NIO SocketChannel Java NIO SocketChannel是连接到TCP网络socket(套接字)的通道.Java NIO相当于Java Networking的sock ...

随机推荐

  1. eclipse绘制activiti无法生成图形

    今天使用eclipse绘制acitiviti,发现无法绘制图形,设置里面勾选也勾选了,同时activiti插件也是最新的,最后发现同时打开了两个eclipse窗口就不支持生成图形,看来只能开一个窗口了 ...

  2. HTTP协议的报文结构

    HTTP 有两类报文: (1) 请求报文----从客户向服务器发送请求报文,见图6-12(a). (2) 响应报文----从服务器到客户的回答,见图6-12(b). 由于 HTTP是面向文本的(tex ...

  3. CSRF token 无法被验证. ----Yii连接数据库后数据库错误日志报错

    CSRF token 无法被验证. 我使用的是mongodb+ yii1.1 What is CSRF, please see the details here.  http://en.wikiped ...

  4. Memcached的使用

    为什么要使用Memcached? 1)高并发访问数据库的痛:死锁 2)磁盘IO之痛 3)读写性能完美 4)超简单的集群搭建Cluster 5)开源 6)性能最佳 7)丰富的成功案例 Memcached ...

  5. springMVC下jsp引用外部js,css等静态资源的解决方法

    直入主题. 1. web.xml对springMVC配置如下: <servlet> <description>Spring MVC配置</description> ...

  6. java.nio.file.Path

    public interface Path extends Comparable<Path>, Iterable<Path>, Watchable 1. A Path repr ...

  7. [经验] 新版SkyIAR、Easy Image X在有些PE里不能运行的解决办法

    [经验] 新版SkyIAR.Easy Image X在有些PE里不能运行的解决办法 xxwl2008 发表于 2013-1-26 11:58:38 https://www.itsk.com/threa ...

  8. unity调用摄像头的方法

    http://blog.csdn.net/cocoa_china/article/details/10527995 using UnityEngine; using System.Collection ...

  9. Unity3D 中的定时器

    不算上 C# 自带的,目前知道两种,以下分别介绍. 1.每帧检查 定义一个时间变量 timer,每帧将此时间减去帧间隔时间 Time.deltaTime,如果小于或者等于零,说明定时器到了,执行相应功 ...

  10. How to run a geoprocessing tool

    How to run a geoprocessing tool In this topic Running a geoprocessing tool Toolbox names and namespa ...