抽象类作为功能接口

Posted

技术标签:

【中文标题】抽象类作为功能接口【英文标题】:Abstract class as functional interface 【发布时间】:2014-08-27 21:54:24 【问题描述】:

在 java 8 中,只有一个抽象方法的抽象类不是函数式接口 (JSR 335)。

这个interface是一个功能接口:

public interface MyFunctionalInterface 
    public abstract void myAbstractMethod();
    public default void method() 
        myAbstractMethod();
    

但是这个abstract class 不是:

public abstract class MyFunctionalAbstractClass 
    public abstract void myAbstractMethod();
    public void method() 
        myAbstractMethod();
    

所以我不能将抽象类用作 lambda 表达式和方法引用的目标。

public class Lambdas 
    public static void main(String[] args) 
        MyFunctionalAbstractClass functionalAbstractClass = () -> ;
    

编译错误为:The target type of this expression must be a functional interface

为什么语言设计者会施加这个限制?

【问题讨论】:

好问题...兼容性可能吗? 这已经被问过并回答过......主要原因是未来的灵活性,预计 lambdas 与类实例有很大不同。 在这里,阅读from the horse's mouth。 @MarkoTopolnik 发布简短摘要和此链接作为答案。我只是讨厌在 cmets 中看到带有答案的“未回答”问题。 :-) @StuartMarks 是的,你是对的。完成。 【参考方案1】:

自从 Lambda 项目开始以来,这一直是一个重要的话题,并引起了很多思考。首席 Java 语言架构师 Brian Goetz 强烈支持将 lambda 视为一个函数,而不是一个对象。引用:

我相信,Java 发展的最佳方向是 鼓励更实用的编程风格。 Lambda的作用是 主要是为了支持更多的发展和消费 类函数库

我对 Java 的未来持乐观态度,但为了向前发展,我们有时 不得不放弃一些舒服的想法。 Lambdas-are-functions 打开 门。 Lambdas-are-objects 关闭它们。我们更喜欢看到那些门 保持打开状态。

Here 是引用源的链接,here 是 Brian 最近的帖子,它重申了相同的哲学观点,并通过更多、更实际的论点重申了它们:

使模型更简单为各种虚拟机打开了大门 优化。 (放弃身份是这里的关键。)功能是 价值观。将它们建模为对象会使它们更重,更复杂, 比他们需要的。

在把这个用例扔到公共汽车下之前,我们做了一些语料库分析 找出与接口相比抽象类 SAM 的使用频率 SAM。我们发现在那个语料库中,只有 3% 的 lambda 候选 内部类实例以抽象类为目标。而且大部分 它们可以进行简单的重构,您在其中添加了 接受以接口为目标的 lambda 的构造函数/工厂。

【讨论】:

我只想补充一点,这是 JSR-335 早期阶段最热门的话题之一。当我们第一次提出“仅接口”规则时,这似乎是有风险的。但由于这件事现在已经解决了好几年,我绝对相信我们做了正确的事情。由于放弃了一些极端用例,我们获得了显着的简单性和灵活性(以更好的性能和更灵活的未来语言发展的形式为所有用户带来)。 我没有看到 Brian Goetz 在这里提供了任何想法。只是一些无意义的词。 Lambda 是匿名内部类的语法糖。那为什么要在糖里加苦?!

以上是关于抽象类作为功能接口的主要内容,如果未能解决你的问题,请参考以下文章

抽象类_作为接口

抽象类与接口

AJPFX关于抽象类和接口的区别

抽象类与接口

接口抽象类

抽象类