- 接口默认方法(Default Methods)
- 函数式接口(SAM类型的接口(Single Abstract Method))
- lambda表达式
- 方法引用
接口默认方法(Default Methods)
接口定义:
public interface FunctionInter { /** * 接口默认方法1 (默认方法可有多个) */ default String testdefaultFunction1(){ System.out.println("testdefaultFunction1"); return "testdefaultFunction1"; } /** * 接口默认方法2 (默认方法可有多个) * @return */ default String testdefaultFunction2(){ System.out.println("testdefaultFunction2"); return "testdefaultFunction2"; } /** * 接口可定义静态变量 */ public static String foo = "foo"; /** * 接口可定义静态方法 * @return */ public static String testFunctionInterStatic(){ System.out.println("testFunctionInter"); return "testFunctionInterStatic"; } /** * 接口可定义抽象方法 */ public abstract void testAbstract(); }
接口实现:
public class FunctionInterfaceTest implements FunctionInter { @Override public void testAbstract() { System.out.println("testAbstract"); } public static void main(String[] args) { FunctionInterfaceTest item = new FunctionInterfaceTest(); //默认方法 item.testdefaultFunction1(); //默认方法 item.testdefaultFunction2(); //抽象方法 item.testAbstract(); //接口静态方法调用 通过接口来调用 FunctionInter.testFunctionInterStatic();// 接口静态方法调用 正确 // item.testFunctionInterStatic(); 接口静态方法调用 错误 // FunctionInterfaceTest.testFunctionInterStatic(); 接口静态方法调用 错误 //接口静态变量调用 通过实现类来调用 System.out.println(FunctionInterfaceTest.foo); //接口静态变量调用 通过接口来调用 System.out.println(FunctionInter.foo); } }
- 接口定义中新增带有默认实现的方法
- 接口定义抽象方法
- 接口定义静态变量和静态实现方法
- 静态变量可被实现类引用,静态实现方法不可以被实现类引用
函数式接口
函数式接口其实本质上还是一个接口,但是它是一种特殊的接口:SAM类型的接口(Single Abstract Method)。定义了这种类型的接口,使得以其为参数的方法,可以在调用时,使用一个lambda表达式作为参数。从另一个方面说,一旦我们调用某方法,可以传入lambda表达式作为参数,则这个方法的参数类型,必定是一个函数式的接口,这个类型会使用@FunctionalInterface进行修饰,或者抽象方法只有一个的接口不用@FunctionalInterface修饰也可作为函数式接口来用。
从SAM原则上讲,这个接口中,只能有一个函数需要被实现,但是也可以有如下例外:
1. 默认方法与静态方法并不影响函数式接口的契约,可以任意使用,即
函数式接口中可以有静态方法,一个或者多个静态方法不会影响SAM接口成为函数式接口,并且静态方法可以提供方法实现
可以由 default 修饰的默认方法方法,这个关键字是Java8中新增的,为的目的就是使得某一些接口,原则上只有一个方法被实现,但是由于历史原因,不得不加入一些方法来兼容整个JDK中的API,所以就需要使用default关键字来定义这样的方法
2. 可以有 Object 中覆盖的方法,也就是 equals,toString,hashcode等方法。
JDK中以前所有的函数式接口都已经使用 @FunctionalInterface 定义,可以通过查看JDK源码来确认,以下附JDK 8之前已有的函数式接口:
java.lang.Runnable
java.util.concurrent.Callable
java.security.PrivilegedAction
java.util.Comparator
java.io.FileFilter
java.nio.file.PathMatcher
java.lang.reflect.InvocationHandler
java.beans.PropertyChangeListener
java.awt.event.ActionListener
javax.swing.event.ChangeListener
函数式接口定义方式1 (不用@FunctionalInterface修饰,但是函数式接口必须只有一个抽象待实现的方法,可以包含其他的默认的实现方法或者静态的已实现方法)
public interface FunctionInterfaceDefine { public String functionBody(); default String defaultBody(){ return "defaultBody"; } }