Java泛型学习笔记 - (六)泛型的继承
在学习继承的时候, 我们已经知道可以将一个子类的对象赋值给其父类的对象, 也就是父类引用指向子类对象, 如:
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泛型学习笔记 - (六)泛型的继承的更多相关文章
- Java IO学习笔记六:NIO到多路复用
作者:Grey 原文地址:Java IO学习笔记六:NIO到多路复用 虽然NIO性能上比BIO要好,参考:Java IO学习笔记五:BIO到NIO 但是NIO也有问题,NIO服务端的示例代码中往往会包 ...
- Java泛型学习笔记 - (一)泛型的介绍
一.什么是泛型:泛型的作用是用来规定一个类, 接口或方法所能接受的数据的类型. 就像在声明方法时指定参数一样, 我们在声明一个类, 接口或方法时, 也可以指定其"类型参数", 也就 ...
- java基础学习笔记六(继承)
继承的概念 继承是java面向对象编程技术的一块基石,因为它允许创建分等级层次的类. 继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父 ...
- java jvm学习笔记六(实现写自己的安全管理器)
安全管理器SecurityManager里设计的内容实在是非常的庞大,它的核心方法就是checkPerssiom这个方法里又调用AccessController的checkPerssiom方法,访问控 ...
- Java IO学习笔记六
打印流 在整个IO包中,打印流是输出信息最方便的类,主要包含字节打印流(PrintStream)和字符打印流(PrintWrite).打印流提供了非常方便的打印功能,可以打印任何的数据类型,例如:小数 ...
- 《Thinking in Java》学习笔记(六)
1.Class相关知识 Class类可以理解为类的图纸,通过Class类可以分析类的结构.构建出类的实例. Class.forName("test.TestClass").newI ...
- Java基础学习笔记六 Java基础语法之类和ArrayList
引用数据类型 引用数据类型分类,提到引用数据类型(类),其实我们对它并不陌生,如使用过的Scanner类.Random类.我们可以把类的类型为两种: 第一种,Java为我们提供好的类,如Scanner ...
- Android(java)学习笔记118:类继承的注意事项
/* 继承的注意事项: A:子类只能继承父类所有非私有的成员(成员方法和成员变量) B:子类不能继承父类的构造方法,但是可以通过super(马上讲)关键字去访问父类构造方法. C:不要为了部分功能而去 ...
- Java NIO学习笔记六 SocketChannel 和 ServerSocketChannel
Java NIO SocketChannel Java NIO SocketChannel是连接到TCP网络socket(套接字)的通道.Java NIO相当于Java Networking的sock ...
随机推荐
- 关于xml配置实现AOP的小知识
除了前面介绍的基于JDK1.5的注解方式来定义切面,切入点和增强处理外,Spring AOP也允许直接使用XML配置文件来管理它们.在JDK1.5之前,只能使用配置文件的方式来管理,在Spring2. ...
- MIT牛人解说数学体系
https://www.douban.com/group/topic/11115261/ 在过去的一年中,我一直在数学的海洋中游荡,research进展不多,对于数学世界的阅历算是有了一些长进. 为什 ...
- Ajax form表单提交
1. 使用 $("form").serialize() 来获取表单数据 $.ajax({ type: 'post', url: 'your url', data: $(" ...
- Android文件存储
文件存储是Android中最基本的一种数据存储方式,它不读存储的内容进行任何的格式化处理,所有数据原封不动的保存在文件之中.如果想用文件存储的方式保存一些较为复杂的数据,就需要定义一套自己的格式规范, ...
- tar 解压常用压缩文件格式命令大全
常用压缩文件格式就那么几种,解压命令总结在此: 1 2 3 4 5 6 7 8 tar xzf filename.tar.gz tar xjf filename.tar.bz2 tar xzf f ...
- 使用vs中的发布功能发布asp.net core项目时遇到ERROR_CERTIFICATE_VALIDATION_FAILED错误
今天将VS2015编制的一个asp.net core项目发布到服务器进行测试,使用的是vs中主菜单"生成"中的"发布"功能. 遇到了一个错误,在网上反复检索尝试 ...
- js写的ajax
1.jsp <%@ page language="java" import="java.util.*" pageEncoding="utf-8& ...
- 0527 Sprint 1 总结
首页 登陆与注册 除登陆和注册之外,我们觉得最主要的是做完登陆和注册的返回功能 界面选项 查询界面 显而易见的我们做了界面之后我们的工作量也减少了,因为相对来讲前期工作比较容易,而各个功能板块所计划的 ...
- cin, cin.getline等函数
char s[100]; cin>>s; // 输入一个字符串,遇“空格”.“TAB”.“回车”都结束 cin.getline(s, 20); // cin.get( ...
- Ubuntu Server 配置网络
------------------ Ubuntu 14.04 x86_64 ----------------- 设置静态IP:vi /etc/network/interfaces. 然后再编辑 ...