引言
上节中简单介绍了泛型基本使用方法及使用泛型带来的安全性和可读性好处,接下来继续思考第二版代码的不足之处。回顾第二版Driver类的drive方法,其接收T泛型参数,为了调用具体car的run方法,需要向下转型,进行了多次instanceof判断,代码冗余且扩展性不好,不符合代码设计的"开闭原则"。有没有更好的方式?
根据“依赖反转”原则,即代码应当依赖于抽象,而不是具体。由于T类型可以是任意具体的类型,所以在方法体中只能当作一般的Object进行处理,那如果可以限制T的具体类型呢,让T类型必须是某个类的子类或实现某个接口呢,那么问题就解决了。请看改进后的代码
第三版
第三版代码如下:
public interface Runnable {
public void run();
}
public class Buick implements Runnable {
@Override
public void run(){
System.out.println("buick run");
}
public void autoRun(){
System.out.println("buick auto-run");
}
}
public class Ford implements Runnable {
@Override
public void run(){
System.out.println("ford run");
}
public void fly(){
System.out.println("ford fly");
}
}
public class Driver<T extends Runnable> {
private T car;
public void drive(T car){
this.car = car;
System.out.println("I am driving a " + car);
car.run();
}
public T getDrivingCar(){
return car;
}
public static void main(String[] args) {
Driver<Ford> driver1 = new Driver<Ford>();
driver1.drive(new Ford());
Driver<Buick> driver2 = new Driver<Buick>();
driver2.drive(new Buick());
//...执行其它业务逻辑
/** 获取司机1开的福特车执行fly方法 */
driver1.getDrivingCar().fly();
/** 获取司机2开的别克车执行autoRun方法 */
driver2.getDrivingCar().autoRun();
}
}
跟前一版本相比,增加了Runnable接口(不要跟多线程的Runnable接口混洧,如有雷同,纯属巧合),Ford和Buick都实现了该接口。最主要的修改在Driver类的泛型T声明上,将<T>改为<Textends Runnable>,这样改的意思是指,T泛型代表任意实现或继承Runnable接口的具体类型,这样就能够在方法体中直接调用Runnable接口中的run方法。
这样改的另一个好处是,由于drive方法接收的参数是基于接口的,这样即使传入参数是另外的车类型(比如奔驰车),代码也不需要进行任何修改,完全符合代码设计中“对扩展开放,对修改关闭”的原则。
泛型声明<T extends Runnable>意味着T类型必须是Runnable接口的子接口或实现类。更一般化的,可以是<T extends Parent>,Parent可以是接口,抽象类或一般类。T具体类型必须是Parent的子类或实现类或Parent自身。
上面介绍了extends关键字在泛型声明中的使用。下面介绍下如何在方法上进行泛型声明并使用。今天就写到这了,明天继续
版权声明:本文为博主原创文章,未经博主允许不得转载。
分享到:
相关推荐
在本月的“Java 理论和实践”中,Brian Goetz 分析了束缚第一次使用泛型的用户的常见陷阱。您可以通过讨论论坛与作者和其他读者分享您对本文的看法。(也可以单击本文顶端或底端的讨论来访问这个论坛。)
Java注解和最佳实践 JavaIO流 多线程 深入理解内部类 javac和javap Java8新特性终极指南 序列化和反序列化 继承、封装、多态的实现原理 容器 Java集合类总结 Java集合详解1:一文读懂ArrayList,Vector与Stack使用...
学习集合:理解Java中的Collection、泛型、List、Set、Collections、Map和HashMap等概念和用法。 掌握异常处理:了解Java的异常体系、异常分类,学会声明、抛出和捕获异常,并自定义异常。 初步掌握多线程:理解线程...
Java的学习过程需要不断地实践和探索,通过编写实际的程序来理解和掌握Java语言。同时,还需要不断地学习和掌握Java语言的新特性和新技术,以适应不断变化的编程环境和需求。 总之,Java是一种强大而灵活的编程语言...
Java注解和最佳实践 JavaIO流 多线程 深入理解内部类 javac和javap Java8新特性终极指南 序列化和反序列化 继承封装多态的实现原理 集合类 Java集合类总结 Java集合详解:一文读懂ArrayList,Vector与Stack使用方法和...
Chock充满了演示如何充分利用现代Java API和开发最佳实践的示例,这本经过全面修订的书籍包含有关Java Concurrency Utilities的新资料。 本书的第一部分提供了Java编程语言和Java平台的核心运行时方面的快节奏,...
《java jdk 7学习笔记》是作者多年来教学实践经验的总结,汇集了教学过程中学生在学习java时遇到的概念、操作、应用或认证考试等问题及解决方案。 《java jdk 7学习笔记》针对java se 7新功能全面改版,无论是...
本书是学习Java 7 新功能和新特性以及深入理解Java 核心技术的最佳选择之一。经过 近6 年的等待,Java 迎来了它的又一个历史性的版本—Java 7 。Java 7 在提高开发人员的 生产效率、平台性能和模块方向上又迈进了...
通过阅读和分析Java源码,可以帮助学习者深入理解Java编程语言的特性和最佳实践,提高编程技能,解决实际问题。同时,Java源码也是开发人员进行软件开发的基础,可以用于构建各种类型的应用程序和系统。 这个Java...
通过阅读和分析Java源码,可以帮助学习者深入理解Java编程语言的特性和最佳实践,提高编程技能,解决实际问题。同时,Java源码也是开发人员进行软件开发的基础,可以用于构建各种类型的应用程序和系统。 这个Java...
通过阅读和分析Java源码,可以帮助学习者深入理解Java编程语言的特性和最佳实践,提高编程技能,解决实际问题。同时,Java源码也是开发人员进行软件开发的基础,可以用于构建各种类型的应用程序和系统。 这个Java...
本书从编程技术、项目实践以及软件工程的角度出发,如果大家想学习基础语法部分,建立去下载别的书籍。当然这本书也讲解了语法,是从实战的角度讲解的。 目录回到顶部↑第1章 进驻爪哇岛——JAVA的基本语法. 1 1.1 ...
本书从编程技术、项目实践以及软件工程的角度出发,如果大家想学习基础语法部分,建立去下载别的书籍。当然这本书也讲解了语法,是从实战的角度讲解的。 目录回到顶部↑第1章 进驻爪哇岛——JAVA的基本语法. 1 1.1 ...
通过阅读和分析Java源码,可以帮助学习者深入理解Java编程语言的特性和最佳实践,提高编程技能,解决实际问题。同时,Java源码也是开发人员进行软件开发的基础,可以用于构建各种类型的应用程序和系统。 这个Java...
通过阅读和分析Java源码,可以帮助学习者深入理解Java编程语言的特性和最佳实践,提高编程技能,解决实际问题。同时,Java源码也是开发人员进行软件开发的基础,可以用于构建各种类型的应用程序和系统。 这个Java...
通过阅读和分析Java源码,可以帮助学习者深入理解Java编程语言的特性和最佳实践,提高编程技能,解决实际问题。同时,Java源码也是开发人员进行软件开发的基础,可以用于构建各种类型的应用程序和系统。 这个Java...
通过阅读和分析Java源码,可以帮助学习者深入理解Java编程语言的特性和最佳实践,提高编程技能,解决实际问题。同时,Java源码也是开发人员进行软件开发的基础,可以用于构建各种类型的应用程序和系统。 这个Java...