本文仅供学习和交流使用,如果您发现我已经侵犯到原作者的版权,请邮件我ttchgm@gmail.com。以便我及时删除和处理。如果翻译有错误或者交流可以随时mail我。或者在sina微博 @天天吃好,私信与我。 本文拒绝任何形式转载。
什么是函数式接口?
一个函数式接口是一个能够使用类函数做为参数的类型,一个lambda表达式支持提供这样一个实参。举个例子,forEach类方法在集合类上有如下签名:
必须为forEach
提供并实现一个Block
接口的一个单例类方法实例
,才能被使用forEach类方法
。这个实例可以是一个lambda表达式
(看 Lambda表达式是什么类型?);如果是这样,他将能被实际应用中替换成类方法。一个lambda表达式提供这样一个方式替换一个接口类方法,所以共性能接口仅能被使用像这样无歧义的单例类方法
中。
更精确的,一个函数式接口
是恰好被定义成一些接口中的抽象类方法
。(这个限制是必须的,因为一个接口会有继承自Object的非抽象类方法
,并且也可以有非抽象默认类方法
。)这就是为什么函数式接口被叫做单例抽象类
(SAM
:Single Abstract Method
)接口`,这个术语比较常见。
例子
下面是来自接口来自多个平台库中是函数式接口的定义:
public interface Runnable { void run(); }
public interface Callable<V> { V call() throws Exception; }
public interface ActionListener { void actionPerformed(ActionEvent e); }
public interface Comparator<T> { int compare(T o1, T o2); boolean equals(Object obj); }
语法注记
- 接口Comparator是功能性的,虽然它显式声明了两个类方法,因为只有一个是抽象的;equals是一个明确声明为继承自Object的具体函数,除了这里的声明,也将会隐式声明。
-
【第一次阅读时跳过这条】 情况可能较难理解,两个接口可以有,擦除(Type erasure)后相同的但完全不同的类方法。举个例子,将个接口的类方法。
interface Foo1 { void bar(List arg); }
interface Foo2 { void bar(List arg); }
是说的覆盖等价
。如果一个接口包含覆盖等价的类方法的多个父接口,这个功能的描述为这个接口定义像一个能覆盖所有被继承的抽象类方法的一个类方法。在这个例子中,如果
interface Foo extends Foo1, Foo2 {}
那么foo的功能描述是
void bar(List arg);
事实上,任何函数式接口都有这样的函数描述,甚至在更多基本和简单例子中仅是单例抽象类方法接口。