Java中接口作为方法的返回
2014-12-10 22:13
162 查看
在《算法》中的散列表一节,在用拉链法实现散列表的API时要求实现以下一个方法:
我们知道Iterable是一个接口,那么一个方法怎么会返回一个接口呢?在《Effective Java》中第52条为“通过接口引用对象”
子类是可以向上转型为父类,因此传递给父类的消息子类是都可以接受的,接口和其实现类有点这样的关系,当然还是有不同。当我们返回一个接口类型时,其实就是意味着,以后你完全可以把其返回值赋给一个实现了此接口的实现类的实例。这样编写的好处是,此接口的实现类的实例在运行时可以任意灵活指定,而不需要修改接口函数的代码。如果有合适的接口类型存在,那么对于参数,返回值,变量和域来说,都应该使用接口类型进行声明。如果没有合适的接口存在,完全可以用类而不是接口来引用对象。
查看JDK的Collections相关的库可以发现大量使用了返回接口来引用对象,例如iterator()这些方法的实现都是返回一个interface,实际只需要实现这个interface即可,对于不同的集合实现interator不一样并不影响iterator的调用。
回到最开始public Iterable<Key> keys()该如何实现,这里采用ArrayList来实现,当然也可以返回其他任何实现了Iterable接口的类:
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中“接口”可以作为方法的返回值吗?
- NDK编程jni学习入门,声明native方法,使其作为java与c的交互接口
- java之interface--接口作为方法的参数传递
- Java基础学习笔记十二 类、抽象类、接口作为方法参数和返回值以及常用API
- [java]类&抽象类&接口分别作为方法参数和返回值
- Flex 对Java端返回Collection的处理方法
- 方法的返回值和this作为普通方法的返回值
- 组件接口方法调用,返回S_FALSE 还是E_FAIL?
- 用sql脚本一条条导数据的两种方法,需返回唯一标识@@IDENTITY作为插入到第二个表用。
- java调用.netwebservice的方法,返回类型为XmlDocument
- dwr例子6调用返回List、Set或者Map的java方法
- [VB.NET]问下 :自己写的com,其中一个接口方法返回一个variant类型的值,在.net中如何接收啊
- Java调用.NET XML Web Services返回的数据集合的方法
- Java多线程初学者指南(8):从线程返回数据的两种方法
- Effective Java Item8-在覆盖equals(Object类的nonfinal方法)时遵循接口规范
- 提高Java代码重用性方法 措施二:把参数类型改成接口
- JAVA使用XML作为持久存储介质实现方法
- java中用静态方法返回类名
- [学习笔记]java Enumeration接口方法的学习