在《算法》中的散列表一节,在用拉链法实现散列表的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中接口作为方法的返回的更多相关文章

  1. java中的compareto方法以及LIst列表排序的详细介绍【转】

    java中的compareto方法的详细介绍 javacompareTo  java中的compareto方法,返回参与比较的前后两个字符串的asc码的差值,看下面一组代码 String a=&quo ...

  2. java中的compareto方法的详细介绍

    java中的compareto方法的详细介绍 Java Comparator接口实例讲解(抽象方法.常用静态/默认方法) 一.java中的compareto方法 1.返回参与比较的前后两个字符串的as ...

  3. Java中的native方法

    博客引用地址:Java中的native方法 今天花了两个小时把一份关于什么是Native Method的英文文章好好了读了一遍,以下是我依据原文的理解. 一. 什么是Native Method 简单地 ...

  4. 详解Java中的clone方法

    详解Java中的clone方法 参考:http://blog.csdn.net/zhangjg_blog/article/details/18369201/ 所谓的复制对象,首先要分配一个和源对象同样 ...

  5. Java中接口是否可以继承多个接口?

    可以. 接口是常量值和方法定义的集合.接口是一种特殊的抽象类. java类是单继承的.classB Extends classA java接口可以多继承.Interface3 Extends Inte ...

  6. 浅谈Java中的hashcode方法

    哈希表这个数据结构想必大多数人都不陌生,而且在很多地方都会利用到hash表来提高查找效率.在Java的Object类中有一个方法: 1 public native int hashCode(); 根据 ...

  7. 千万不要误用 java 中的 HashCode 方法

    刚才debug追堆栈的时候发现一个很奇怪的问题 我用IE8和Google的浏览器访问同一个地址 Action的 scope="session" 也设置了 而且两个浏览器提交的参数m ...

  8. Java中的toString()方法

    Java中的toString()方法 目录 Java中的toString()方法 1.    对象的toString方法 2.    基本类型的toString方法 3.    数组的toString ...

  9. Java中的main()方法详解

    在Java中,main()方法是Java应用程序的入口方法,也就是说,程序在运行的时候,第一个执行的方法就是main()方法,这个方法和其他的方法有很大的不同,比如方法的名字必须是main,方法必须是 ...

随机推荐

  1. Win7下Maven的安装与配置

    简介  官网:https://maven.apache.org/ Apache Maven,是一个(特别是Java软件)项目管理及自动构建工具,由Apache软件基金会所提供.基于项目对象模型(Pro ...

  2. android 获取字符串的方法

    字符串数组可以在value文件夹中声明: 书写的内容是: 两者的读取方式略有不同: 如果是读取数字的话,  使用: context.getResources().getStringArray( R.a ...

  3. 30 个很棒的 PHP 开源 CMS 内容管理系统

    本文汇集了30个优秀的开源CMS建站系统,采用PHP开发.以下列表不分先后顺序. 1. AdaptCMS AdaptCMS Lite 是一个开源的CMS系统,主要特点是易用,而且可以轻松和其他系统接驳 ...

  4. <<薪资至少10K的一道题,你能拿下吗>>练习

    偶尔要写写算法,是我平时用来保持感觉的常用的方法.今天看到园子里一面试题,看了一下感觉也能实现,不过过程确实艰的,自认为自己对算法的感觉还不错.不过这题确实我也用了差不多一下午的时间,基本上把工作时间 ...

  5. VS复习 -- if···else和if···else嵌套语句

    注意:理清逻辑,画出逻辑分支图,理清思路 1.if语句 2.if...else语句 3.if..else if...else static void Main(string[] args) { Con ...

  6. Mysql 字符串处理函数

    函数: 1.从左开始截取字符串 left(str, length) 说明:left(被截取字段,截取长度) 例:select left(content,200) as abstract from my ...

  7. Asp.Net MVC EF各版本区别

      2009年發行ASP.NET MVC 1.0版 2010年發行ASP.NET MVC 2.0版,VS2010 2011年發行ASP.NET MVC 3.0版+EF4,需要.Net4.0支持,VS2 ...

  8. DBCC DBREINDEX重建索引提高SQL Server性能

    大多数SQL Server表需要索引来提高数据的访问速度,如果没有索引,SQL Server 要进行表格扫描读取表中的每一个记录才能找到索要的数据.索引可以分为簇索引和非簇索引,簇索引通过重排表中的数 ...

  9. 第一个简单的DEMO

    一个联系人管理的DEMO,支持CURD 运行效果图: Controller的设计: 总结: Web API的Controller都继承自ApiController. Web API的Action的命名 ...

  10. easyui layout 收缩的bug

    easyui layout提供collapse方法折叠指定的 panel,'region' 参数可能的值是:'north'.'south'.'east'.'west',但是在 IE6的环境下,调用这个 ...