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 ...
随机推荐
- DOM常用操作总结
一.getElementById() 寻找一个有着给定 id 属性值的元素,返回值是一个有着给定 id 属性值的元素节点.如果不存在,这样的元素,它返回 null. 二.getElementsByNa ...
- java归并排序,单线程vs多线程
一.什么是归并排序 归并排序又称合并排序,它是成功应用分治技术的一个完美例子.对于一个需要排序的数组A[0..n-1],归并排序把它一分为二:A[0..n/2-1]和A[n/2..n-1],并对每个子 ...
- idea中配置eslint 静态代码检查
配置: 1,安装依赖 sudo tnpm install eslint -g sudo tnpm install eslint-plugin-import -g sudo tnpm install e ...
- FirstUniqueCharacterInString
Given a string, find the first non-repeating character in it and return it's index. If it doesn't ex ...
- Redis教程(二):String数据类型
一.概述: 字符串类型是Redis中最为基础的数据存储类型,它在Redis中是二进制安全的,这便意味着该类型可以接受任何格式的数据,如JPEG图像数据或Json对象描述信息等.在Redis中字符串类型 ...
- java ZipOutputStream压缩文件,ZipInputStream解压缩
java中实现zip的压缩与解压缩.java自带的 能实现的功能比较有限. 本程序功能:实现简单的压缩和解压缩,压缩文件夹下的所有文件(文件过滤的话需要对File进一步细节处理). 对中文的支持需要使 ...
- 12 个CSS 高级技巧汇总[转载]
使用 :not() 在菜单上应用/取消应用边框 给body添加行高 所有一切都垂直居中 逗号分隔的列表 使用负的 nth-child 选择项目 对图标使用SVG 优化显示文本 对纯CSS滑块使用 ma ...
- GNS3 IOU 配置
GNS3使用视频: http://edu.51cto.com/lesson/id-25295.html GNS3 IOU 与VM http://www.mamicode.com/info-detail ...
- phantomjs+selenium实现爬取动态网址
之前使用 selenium + firefox驱动浏览器来实现爬取动态网址,但是firefox经常更新,更新后时常会导致webdriver启动不来,所以改用phantomjs+selenium来改善一 ...
- java-方法练习
一.定义方法的最主要的两个步骤: 1.先明确结果(即返回值类型要先明确) 2. 在实现功能时是否有未知内容参与运算,即明确函数的参数列表(参数类型,参数个数) 例如:定义一个九九乘法表的功能. 思路 ...