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

 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. 【转】linux下安装ssh服务器端及ssh的安全配置

    一.在服务器上安装ssh的服务器端. $ sudo apt-get install openssh-server 2. 启动ssh-server. $ /etc/init.d/sshrestart 3 ...

  2. asp.net 获取汉字字符串的拼音首字母,含多音字

    需求:在很多时候数据查询的时候,我们希望输入某个人姓名的拼音首字母进行查询,例如“潘长江”,输入“pcj”,就能搜索潘长江相关信息. 实现: #region 获取汉字转换拼音 首字母 public s ...

  3. text-decoration

    2016-08-18  text-decoration  blink貌似在firefox里也不起作用? <p style="color:red;text-decoration:unde ...

  4. IDE编辑器编码配置

    做跨平台开发时,大家用不同的IDE合作开发,最令人头疼的事就是各种乱码问题. 常用的IDE都支持utf-8编码和unix格式行尾'\n'. 1.XCODE设置文本编码及换行Xcode >> ...

  5. css3新增选择器

    1. img[alt]:匹配页面标签中任意一个含有alt属性的标签 2. 匹配开头:img[alt^="film"] 匹配包含内容:img[alt*="film" ...

  6. 通过页面调用APP【H5与APP互通】

    现在H5和App原生的内容原来越互通,所涉及的业务也越来越复杂和融合,所以如何互相之间方便的调用才是王道. 场景1 比如用hybrid获取地理位置和短信信息,这当然需要框架封装好,比如利用框架的bri ...

  7. C# Socket连接 无法访问已释放的对象

    在进行Socket长连接时,若服务器或客户端出现异常时,另外一端对Socket对话进行操作时,程序会出现无法访问已释放的对象的问题.例如客户端出现问题主动断开Socket时,当服务器操作Socket时 ...

  8. 使用dreamweaver去掉文本中的空格和换行

    当我们从其他地方拷贝文本到网页,在html代码中会自动带有空格和换行,手动去掉很麻烦,今天试着用dreamweaver去了一下,方法如下: 1.点击Ctrl+F,打开“查找和替换”窗口 2‘见下图:

  9. 2016年最佳Linux发行版排行榜

    2015年,不管在企业市场还是个人消费市场都是 Linux 非常重要的一年. 最好的回归发行版:openSUSE openSUSE 背后的 SUSE 公司是最老的 Linux 企业,它成立于 Linu ...

  10. python【0】-目录

    python[1]-基础知识 Python[2]-列表和元组 Python[3]-字典dic和集合set python[4]-函数 python[5]-生成式,生成器 python[6]-函数式编程 ...