Java中接口作为方法的返回
在《算法》中的散列表一节,在用拉链法实现散列表的API时要求实现以下一个方法:
public Iterable<Key> keys()
我们知道Iterable是一个接口,那么一个方法怎么会返回一个接口呢?在《Effective Java》中第52条为“通过接口引用对象”
as parameter types. More generally, you should favor the use of interfaces rather than classes to refer to objects. If appropriate interface types exist, then parameters, return values, variables, and fields should all be declared using interface types. The only time you really need to refer to an object’s class is when you’re creating it with a constructor. To make this concrete, consider the case of Vector, which is an implementation of the List interface. Get in the habit of typing this: // Good - uses interface as type
List<Subscriber> subscribers = new Vector<Subscriber>(); rather than this: // Bad - uses class as type!
Vector<Subscriber> subscribers = new Vector<Subscriber>(); If you get into the habit of using interfaces as types, your program will be much more flexible. If you decide that you want to switch implementations, all you have to do is change the class name in the constructor (or use a different static factory). For example, the first declaration could be changed to read List<Subscriber> subscribers = new ArrayList<Subscriber>(); and all of the surrounding code would continue to work. The surrounding code was unaware of the old implementation type, so it would be oblivious to the change. There is one caveat: if the original implementation offered some special functionality not required by the general contract of the interface and the code depended on that functionality, then it is critical that the new implementation provide the same functionality. It is entirely appropriate to refer to an object by a class rather than an interface if no appropriate interface exists. For example, consider value classes, such as String and BigInteger. Value classes are rarely written with multiple implementations in mind. They are often final and rarely have corresponding interfaces. It is perfectly appropriate to use such a value class as a
parameter, variable, field, or return type. More generally, if a concrete class has no associated interface, then you have no choice but to refer to it by its class whether or not it represents a value. The Random class falls into this category. A second case in which there is no appropriate interface type is that of objects belonging to a framework whose fundamental types are classes rather than interfaces. If an object belongs to such a class-based framework, it is preferable to refer to it by the relevant base class, which is typically abstract, rather than by its implementation class. The java.util.TimerTask class falls into this category. A final case in which there is no appropriate interface type is that of classes that implement an interface but provide extra methods not found in the interface— for example, LinkedHashMap. Such a class should be used to refer to its instances only if the program relies on the extra methods. It should rarely be used as a parameter type (Item 40). These cases are not meant to be exhaustive but merely to convey the flavor of situations where it is appropriate to refer to an object by its class. In practice, it should be apparent whether a given object has an appropriate interface. If it does, your program will be more flexible if you use the interface to refer to the object; if not, just use the least specific class in the class hierarchy that provides the required functionality. Reference: Effective Java 2nd Edition by Joshua Bloch
子类是可以向上转型为父类,因此传递给父类的消息子类是都可以接受的,接口和其实现类有点这样的关系,当然还是有不同。当我们返回一个接口类型时,其实就是意味着,以后你完全可以把其返回值赋给一个实现了此接口的实现类的实例。这样编写的好处是,此接口的实现类的实例在运行时可以任意灵活指定,而不需要修改接口函数的代码。如果有合适的接口类型存在,那么对于参数,返回值,变量和域来说,都应该使用接口类型进行声明。如果没有合适的接口存在,完全可以用类而不是接口来引用对象。
查看JDK的Collections相关的库可以发现大量使用了返回接口来引用对象,例如iterator()这些方法的实现都是返回一个interface,实际只需要实现这个interface即可,对于不同的集合实现interator不一样并不影响iterator的调用。
回到最开始public Iterable<Key> keys()该如何实现,这里采用ArrayList来实现,当然也可以返回其他任何实现了Iterable接口的类:
public Iterable<Key> keys() {
ArrayList<Key> ka = new ArrayList<Key>();
for (int i = 0; i < M; i++) {
ka.addAll(st[i].keys());
}
return ka;
}
Java中接口作为方法的返回的更多相关文章
- java中的compareto方法以及LIst列表排序的详细介绍【转】
java中的compareto方法的详细介绍 javacompareTo java中的compareto方法,返回参与比较的前后两个字符串的asc码的差值,看下面一组代码 String a=&quo ...
- java中的compareto方法的详细介绍
java中的compareto方法的详细介绍 Java Comparator接口实例讲解(抽象方法.常用静态/默认方法) 一.java中的compareto方法 1.返回参与比较的前后两个字符串的as ...
- Java中的native方法
博客引用地址:Java中的native方法 今天花了两个小时把一份关于什么是Native Method的英文文章好好了读了一遍,以下是我依据原文的理解. 一. 什么是Native Method 简单地 ...
- 详解Java中的clone方法
详解Java中的clone方法 参考:http://blog.csdn.net/zhangjg_blog/article/details/18369201/ 所谓的复制对象,首先要分配一个和源对象同样 ...
- Java中接口是否可以继承多个接口?
可以. 接口是常量值和方法定义的集合.接口是一种特殊的抽象类. java类是单继承的.classB Extends classA java接口可以多继承.Interface3 Extends Inte ...
- 浅谈Java中的hashcode方法
哈希表这个数据结构想必大多数人都不陌生,而且在很多地方都会利用到hash表来提高查找效率.在Java的Object类中有一个方法: 1 public native int hashCode(); 根据 ...
- 千万不要误用 java 中的 HashCode 方法
刚才debug追堆栈的时候发现一个很奇怪的问题 我用IE8和Google的浏览器访问同一个地址 Action的 scope="session" 也设置了 而且两个浏览器提交的参数m ...
- Java中的toString()方法
Java中的toString()方法 目录 Java中的toString()方法 1. 对象的toString方法 2. 基本类型的toString方法 3. 数组的toString ...
- Java中的main()方法详解
在Java中,main()方法是Java应用程序的入口方法,也就是说,程序在运行的时候,第一个执行的方法就是main()方法,这个方法和其他的方法有很大的不同,比如方法的名字必须是main,方法必须是 ...
随机推荐
- [saiku] 优化多维度查询效率
1.优化查询精度 优化原因:当维度过多时,查询很复杂,效率较慢.因此看能否通过优化sql的方式来提高查询效率. 代码跟踪查看(维度多余3时查询条件里面有in,优化不用in关键字) public abs ...
- mouseenter和mouseout中间的时间控制
为了防止鼠标快速滑过div而加的时间限制: 在看延迟绑定时候看到,这也算是延迟绑定了?:(20130909) <!DOCTYPE html> <html lang="en& ...
- 设置JVM参数,查看堆大小
1.在eclipse设置JVM参数 打开eclipse-窗口-首选项-Java-已安装的JRE(对在当前开发环境中运行的java程序皆生效,也就是在eclipse中运行的java程序)编辑当前 ...
- 看懂UML图
看懂UML类图和时序图 这里不会将UML的各种元素都提到,我只想讲讲类图中各个类之间的关系: 能看懂类图中各个类之间的线条.箭头代表什么意思后,也就足够应对 日常的工作和交流: 同时,我们应该能将类图 ...
- Java并发编程:阻塞队列(转载)
Java并发编程:阻塞队列 在前面几篇文章中,我们讨论了同步容器(Hashtable.Vector),也讨论了并发容器(ConcurrentHashMap.CopyOnWriteArrayList), ...
- IO流--字节流
import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.FileInputStream; import ...
- hdu5884 Sort(二分+k叉哈夫曼树)
题目链接:hdu5884 Sort 题意:n个有序序列的归并排序.每次可以选择不超过k个序列进行合并,合并代价为这些序列的长度和.总的合并代价不能超过T, 问k最小是多少. 题解:先二分k,然后在k给 ...
- java操作字符串,重点是记录一次使用replaceAll对字符串的操作
符串常用操作(String类) 字符串查找 String提供了两种查找字符串的方法,即indexOf与lastIndexOf方法. 1.indexOf(String s) 该方法用于返回参数字符串s在 ...
- Spring使用RowMapper将数据中的每一行封装成用户定义的类
1.dao public interface MapperSelecteAllEmpDao { public List<Emp> all(); } 2.实现类 public class M ...
- 玩转linux文件(重点)
一.几个主要的操作 mkdir—创建目录 cp—复制文件和目录 mv——移动/重命名文件和目录 rm——删除文件和目录 ln——创建硬链接和软链接 二.几个考点: 通配符 硬链接和软链接(符号链接) ...