使用通配符和泛型:完成父子类关系的List对象的类型匹配
泛型和通配符
使用泛型和通配符都可以让一个方法所表示的算法逻辑适应多种类型。
Java中具备继承关系的类A、B(A extends B)它们的集合List<A>和List<B>之间是没有继承关系的,
可以使用泛型或通配符来让一个方法支持同时接受List<A>和List<B>。
代码场景
这里分别定义类Animal、Dog和Cat,很显然,Dog和Cat是Animal的子类。
它们的简单定义如下:
abstract class Animal {
public abstract boolean afraidOf(Animal other);
}
class Cat extends Animal {
@Override
public boolean afraidOf(Animal other) {
if (other instanceof Dog) {
return true;
}
return false;
}
}
class Dog extends Animal {
@Override
public boolean afraidOf(Animal other) {
if (other instanceof Cat) {
return false;
}
return true;
}
}
上面Animal类定义了boolean afraidOf(Animal other)方法,表示一个动物是否害怕另一个动物。
可以看到Cat和Dog有着不同的表现。
假设有下面需求:
从一个List<Animal>中找到某个Animal对象害怕的所有其它动物。
对应有以下的API方法:
public List<Animal> findScaredAnimals(List<Animal> animals, Animal who) {
//...
}
如果这时有List<Dog>或者List<Cat>这种,也应该是支持的。
可以通过通配符或者泛型方法实现。
通配符实现
使用List<? extends Animal>这样的形参,就可以接收集合项为Animal子类的任意List。
public List<Animal> findScaredAnimals(List<? extends Animal> animals, Animal who) {
//...
}
这时就可以这样调用了:
List<Dog> dogs;
....
findScaredAnimals(dogs, animal);
...
其他Animal子类的List都是可以的。
泛型方法实现
抛开实际意义,假设需要findScaredAnimals()中,返回值和参数对应的具体Animal子类型是一致的,那么就需要用到泛型了:
public <T extends Animal> List<T> findScaredAnimals(List<T> animals, T who) {
//...
}
可以看到,泛型类型参数T同时约束了多个地方。
泛型参数也可以是多个的,而且之间存在关系。
小结
以上通过一个不太实际的案例说明了使用泛型和通配符来解决List泛型集合之间的“匹配”问题。这也是它们的主要用途之一。
(本文使用Atom编写)
使用通配符和泛型:完成父子类关系的List对象的类型匹配的更多相关文章
- 7. Orcle树形结构(类似数据字典有父子类关系),查询末节点的所有记录
SELECT a.*FROM tablename aWHERE NOT EXISTS (SELECT 1 FROM tablename b WHERE b.Fid = a.id)START WITH ...
- java内部类、接口、集合框架、泛型、工具类、实现类
.t1 { background-color: #ff8080; width: 1100px; height: 40px } 一.内部类 1.成员内部类. (1)成员内部类的实例化: 外部类名.内部类 ...
- java数据类型:集合存储元素类型限制<泛型> ;自定义类指定泛型<T> 以及限制用法;派生子类泛型<T> super(泛型内参数); 泛型通配符?以及?限制用法
问题背景 Java 集合有个缺点,把一个对象"丢进"集合里之后,集合就会"忘记"这个对象的数据类型,当再次取出该对象时 该对象的编译类型就变Object类型(其 ...
- Spring和SpringMVC父子容器关系初窥
一.背景 最近由于项目的包扫描出现了问题,在解决问题的过程中,偶然发现了Spring和SpringMVC是有父子容器关系的,而且正是因为这个才往往会出现包扫描的问题,我们在此来分析和理解Spring和 ...
- C++父子类继承时的隐藏、覆盖、重载
存在父子类继承关系时,若有同名成员函数同时存在,会发生隐藏.覆盖和重载这几种情况.对于初学者也比较容易混淆,为此,我整理了一下我的个人看法,仅供参考.希望对大家理解有帮助,也欢迎指正. 1.父子类继承 ...
- SpringMVC与Spring的父子容器关系
问题: 在整合框架的时候有人也许会产生一个问题:能不能只配置一个扫描包加载实现类的扫描驱动,即在根目录下扫描所有的注解(@Controller.@Service.@Repository.@Compne ...
- JAVA基础--JAVA 集合框架(泛型、file类)16
一.集合总结 集合:Collection体系.Map体系. Collection体系:单列集合的共性操作规则. List:列表,可以重复,有下标,拥有特有的迭代器ListIterator. Array ...
- JAVA基础--JAVA 集合框架(泛型、file类)
一.集合总结 集合:Collection体系.Map体系. Collection体系:单列集合的共性操作规则. List:列表,可以重复,有下标,拥有特有的迭代器ListIterator. Array ...
- 这一次搞懂Spring Web零xml配置原理以及父子容器关系
前言 在使用Spring和SpringMVC的老版本进行开发时,我们需要配置很多的xml文件,非常的繁琐,总是让用户自行选择配置也是非常不好的.基于约定大于配置的规定,Spring提供了很多注解帮助我 ...
随机推荐
- RESTful Web服务与“大”Web服务: 做出正确的建筑决策
猜测:REST服务的不足之处 问题:WS- *与REST的争论 结论:REST在灵活性和控制方面得分更高,但需要大量的低级编码; WS- *提供更好的工具支持和编程接口方便,但引入了对供应商和开源项目 ...
- Unity 3D 如何修改新建脚本中的 C# 默认创建的 Script 脚本格式
首先在Unity的安装路径下找到 Unity5\Editor\Data\Resources\ScriptTemplates路径的(81-C# Script-NewBehaviourScript.cs. ...
- C++实现词法分析器
#include <iostream> #include <stdlib.h> #include <stdio.h> using namespace std; ]= ...
- 使用Json.net对Json进行遍历
公司使用了一种伪Json, 当value为字符串并且以"@"开头时, 要替换成真实的值, 比如{"name":"@countryName"} ...
- centos-0 基础
netstat -nap #会列出所有正在使用的端口及关联的进程/应用kill -9 1777 #杀掉编号为1777的进程(请根据实际情况输入) http://www.cnblogs.c ...
- 自定义扩展实现相对于addRoutes的removeRoutes方法——vue-router
使用vue-router的addRoutes方法做登录权限控制,当用户推出登录回到login页后,切换不同权限的账号,如果不reload页面,会导致router权限问题,故在vue-router代码中 ...
- 杨其菊201771010134《面向对象程序设计(java)》第十四周学习总结
第十四周学习总结 第一部分:理论知识 理论知识:本周学习Swing用户界面 内容:Swing与模型-视图-控制器设计模式:布局管理概述:文本输入 :选择组件:菜单:复杂的布局管理:对话框: 第二部分: ...
- python 15 常用模块三 re模块
一.正则模块 正则表达式(或 RE)是一种小型的.高度专业化的编程语言,(在Python中)它内嵌在Python中,并通过 re 模块实现.正则表达式模式被编译成一系列的字节码,然后由用 C 编写的匹 ...
- HTML 中使用 JavaScript
在 HTML 中插入 JavaScript 的主要方法,就是使用 <script> 元素, 浏览器会解释并执行其中的 JavaScript 代码. <script> 元素的属 ...
- Unique Letter String LT828
A character is unique in string S if it occurs exactly once in it. For example, in string S = " ...