java泛型 generics --- 第三部分 泛型、继承、和子类型

Generics, Inheritance, and Subtypes

正如你所知,可以把一种对象类型赋值给另一种类型,只要他们是兼容的。例如,你可以把Integer对象赋值给Object。

Object someObject = new Object();
Integer someInteger = new Integer(10);
someObject = someInteger;   // OK

在面向对象技术中,这被称作“is a"关系。即一个Integer是一中Object,该赋值是允许的。同样,下面代码段也是有效的:

public void someMethod(Number n) { /* ... */ }
someMethod(new Integer(10));   // OK
someMethod(new Double(10.1));   // OK

上面的原则同样适用于泛型:

Box<Number> box = new Box<Number>();
box.add(new Integer(10));   // OK
box.add(new Double(10.1));  // OK

限制考虑下面的方法:

public void boxTest(Box<Number> n) { /* ... */ }

现在考虑这个方法接受什么样的参数类型?它的签名告诉我们,它只接受单一的参数Box<Number>。

这意味着什么?我们可以传人Box<Integer> 或是 Box<Double>吗?答案是否定的。因为它们不是Box<Number>的子类型。

这是泛型编程中经常出现的误解,这是一个很重要的值得学习的概念。


尽管Integer是Number的子类型,但是Box<Integer> 不是 Box<Number>的子类型


Note: 任何具体的类型A和B,如Number与Integer,MyClass<A>和MyClass<B>没有关系,不管A和B是否有关系。 MyClass<A>与 MyClass<B>的共同父类是Object。

当参量类型有关系时,如何在两个子泛型类之间建立像子类型之间的关系,请参考通配符和子类型。


泛型类与子类型化

通过子类型化一个类或是接口,你可以扩展或是实现它。一个类或接口的类型参量与另一个类或接口的类型参量的关系,由扩展或是实现的语句决定。

使用集合类Collections做例子: ArrayList<E>实现 List<E>;List<E>继承(扩展)Collection<E>。

因此,ArrayList<String>是List<String>的子类化,List<String>是Collection<String>的子类化。只要不改变类型参数,它们的子类型化关系是不变得。


 Collections 体系例子

现在假设我们要定义自己的列表接口PayloadList,它关联一个泛型类型P的值和与每一个元素。声明可能看起来是:

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

下面PayloadList的参量化都是List<String>的子类型化:

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

PayloadList体系例子

原文地址https://docs.oracle.com/javase/tutorial/java/generics/inheritance.html

时间: 2024-10-08 20:32:06

java泛型 generics --- 第三部分 泛型、继承、和子类型的相关文章

Java基础——集合(三)——泛型、增强for、工具类

         接上篇,<Java基础--集合(二)--迭代器.Map集合> 六.泛型 (1)定义: 泛型是一种把明确类型的工作放在了创建对象或者调用方法时候才去明确的特殊的类型. (2)格式: <数据类型> ArrayList<String> aList=new ArrayList<String>(); <String> 即表示的是泛型 (3)好处:(掌握) A:解决了黄色警告线问题 B:把运行期间的转换异常给提前到了编译期间 C:优化了程序

泛型(四)——泛型类型的继承规则

在使用泛型类时,需要了解一些有关继承和子类型的准则.子类继承父类的泛型要么子类和父类都不用泛型,要么子类大于等于父类类型.而属性类型:在父类中,随父类而定,在子类中,随子类而定:重写方法:随父类而定. package generic; /** * 泛型类继承规则: * 要么同时擦除,要么子类大于等于父类类型 * 1.属性类型 * 在父类中,随父类而定 * 在子类中,随子类而定 * 2.方法重写 * 随父类而定 * @author 堕落梦醒 * * @param <T> */ public ab

Java 泛型(Generics) 综述

一. 引子 一般的类和方法,只能使用具体类型:要么是基本类型,要么是自定义类型.如果要编写可以应用于多种类型的代码,这种刻板的限制对代码的束缚就会很大. 多态算是一种泛化机制,但对代码的约束还是太强(要么继承父类,要么实现接口). 有许多原因促成了泛型的出现,而最引人注目的一个原因,就是为了创造容器类.(泛型的主要目的之一就是用来指定容器要持有什么类型的对象,而且由编译器来保证类型的正确性) 例如,在 Java 实现加入泛型前,ArrayList 只维护一个 Object 类型的数组: publ

Java泛型读书笔记 (三)

泛型对于老代码的支持 Java的泛型设计成类型擦除的目的,很大一部分是为了兼容老老代码.如下的一段代码: void setLabelTable(Dictionary table) table的类型是非泛型的Dictionary,但是我们可以传入泛型的Dictionary: Dictionary<Integer, Component> labelTable = new Hashtable<>(); labelTable.put(0, new JLabel(new ImageIcon(

Java 语法 索引 ----- 泛型(Generics)

class B<T extends A> {} class A {} -------------------------- class C<T extends I> {} interface I {} ----------------------- class D<T extends A & I> {} class E<T extends A & I, U extends A & I> {} 参考文献: Java Quick Synt

Java泛型Generics

转载请标明出处: http://blog.csdn.net/wu_wxc/article/details/51493181 泛型 泛型是JDK 5中引入的一个新特性 在尖括号中包含的是形式类型参数,可以在整个类的声明中被使用,当类被使用时,会使用具体的实际类型参数来代替 形式类型参数的命名:尽量使用单个大写字母 普通泛型 一个泛型类型 package cn.wuxiaocheng; class Person<T> { // 标识符可以随便写,T是type的简称 private T name;

一起学 Java集合框架、数据结构、泛型

一.Java 集合框架 集合框架是一个用来代表和操纵集合的统一架构.所有的集合框架都包含如下内容: 接口:是代表集合的抽象数据类型.接口允许集合独立操纵其代表的细节.在面向对象的语言,接口通常形成一个层次. 实现(类):是集合接口的具体实现.从本质上讲,它们是可重复使用的数据结构. 算法:是实现集合接口的对象里的方法执行的一些有用的计算,例如:搜索和排序.这些算法被称为多态,那是因为相同的方法可以在相似的接口上有着不同的实现. 集合接口 序号 name 接口描述 1 Collection Col

Java下的框架编程(反射,泛型,元数据,CGLib,代码动态生成,AOP,动态语言嵌入)

Java 虽然没有动态语言般暴起,但仍然天连天,水接水的生出好多框架技术---反射(reflection),泛型(generics),元数据(annotation),proxies(proxy/cglib),代码动态生成(asm),AOP(aspectJ),动态语言嵌入(groovy/javascript/beanshell).面对着这些,我们像一夜暴富的农企,有点手足无措的样子. 反射是一种让框架能够根据 "以字符串形式存在的信息" 来调用对象的属性和函数的技术,是Java对C++最

java泛型(二)、泛型的内部原理:类型擦除以及类型擦除带来的问题

java泛型(二).泛型的内部原理:类型擦除以及类型擦除带来的问题 参考:java核心技术 一.Java泛型的实现方法:类型擦除 前面已经说了,Java的泛型是伪泛型.为什么说Java的泛型是伪泛型呢?因为,在编译期间,所有的泛型信息都会被擦除掉.正确理解泛型概念的首要前提是理解类型擦出(type erasure). Java中的泛型基本上都是在编译器这个层次来实现的.在生成的Java字节码中是不包含泛型中的类型信息的.使用泛型的时候加上的类型参数,会在编译器在编译的时候去掉.这个过程就称为类型