关于Java 8:Java 8 – 功能接口与抽象类

Java 8 - Functional Interface vs Abstract class

本问题已经有最佳答案,请猛点这里访问。

我正在探索Java 8的特性,并遇到了"功能界面"。

根据我的理解,这些接口可以有一些默认的实现方法:

1
2
3
4
5
6
7
8
9
10
11
12
@FunctionalInterface
public interface ComplexFunctionalInterface extends SimpleFuncInterface
{
    default public void doSomeWork()
    {
        System.out.println("Doing some work in interface impl...");
    }
    default public void doSomeOtherWork()
    {
        System.out.println("Doing some other work in interface impl...");
    }
}

但我怀疑,抽象类就是为了这个。

为什么要引入功能接口?


But my doubt is, this what abstract class is for.

Why introduce functional interfaces.

可扩展的类数:1

可实现的接口数:more than 1


函数接口用于"安全"多重继承。差异:

  • 类可以扩展多个功能接口。
  • 函数接口只能有一个抽象方法。
  • 功能接口可能没有与C++抽象类不同的字段。
  • 小精灵

    典型的用法是当您希望将默认功能嵌入到对象中时。也就是说,如果你有一个像物体一样的功能,

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    class MyFunction1 {
        public Integer apply(String s){
            ...
        }
    }

    class MyFunction2 {
        public List<String> apply(Integer s){
            ...
        }
    }

    如果你想用它们做一个合成,你只需在implements Function中加入:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    class MyFunction1 implements Function<String, Integer>{
        public Integer apply(String s){
            ...
        }
    }

    class MyFunction2 implements Function<Integer, List<String>>{
        public List<String> apply(Integer s){
            ...
        }
    }

    您可以创建函数的组合。比较了两种方法:

    无功能接口:

    1
    2
    3
    4
    MyFunction1 myFunction1 = ...;
    MyFunction2 myFunction2 = ...;

    Function<String, List<String>> composition = (s) -> myFunction2.apply(myFunction1.apply(s));

    具有功能接口:

    1
    2
    3
    4
    MyFunction1 myFunction1 = ...;
    MyFunction2 myFunction2 = ...;

    Function<String, List<String>> composition = myFunction1.andThen(myFunction2);

    区别

    • 无需重新实现功能。
    • 扩展类中可用的其他函数:composeidentity
    • 新的默认函数是类层次结构的一部分,不需要创建新的对象。通常,像compose()这样的函数不会包含在类定义中,因为它会导致类大小的增长。它们通常被放入单独的实用程序类中。在guava中,composition被放入一个单独的实用程序类Functions:functions.composite。因此,对于新的函数接口,您不需要回忆在哪个实用程序类中实现了您的函数。
    • 小精灵


      功能接口必须只有一个方法。唯一的例外是在对象中声明的mehtods。参见http://java.dzone.com/articles/introduction-functional-1


      虽然接口比较器显式声明了两个方法,但它是功能性的,因为只有一个方法是抽象的;equals是从对象继承的具体方法的显式声明,如果没有此声明,则将隐式声明该方法。


      我还没有Java 8的经验,但从我可以看到的,这将允许一种多重继承,这是不可能的抽象类。