一、函数式接口
在学习lambda表达式中,我们知道只有含有一个方法的接口可以用来转换成lambda表达式来使用。而在java8中,将这些接口称为函数式接口。
函数接口指的是只有一个函数的接口,这样的接口可以隐式转换为Lambda表达式。java.lang.Runnable和java.util.concurrent.Callable是函数式接口的最佳例子。
在实践中,函数式接口很脆弱,因为只要多写一个方法该接口就不是函数式接口。为此,java8提供了新的注解;
@FunctionalInterface
public interface Function{
void function();
}
但是,默认方法和静态方法不会破坏函数式接口的定义。
@FunctionalInterface
public interface Function{
void function();
default void defaultFunction();
}
上面这种写法是正确的函数式接口定义。
二、接口的默认方法和静态方法
1、静态方法
与类的静态方法类似,该方法的调用为类名.方法名。该方法只属于这个接口,即便是类implement了这个接口,也无法获得这个方法。只能采用接口名调用。
2、默认方法
(1)默认方法的优势
假设我们已经设计出了一个汽车的系统。他的功能已经都放在一个接口中。当我们希望汽车有新的功能,比方说飞起来,我们就需要在接口中写入飞的抽象方法,再在一个个类中去实现。在java8中,我们可以使用默认方法。将”飞“作为一个默认方法,这样每个类中就有了这个方法,就无需再在每一个类中实现这个方法。这就是默认方法所带来的便利
(2)默认方法使用
接口默认方法的”类优先”原则
若一个接口中定义了一个默认方法,而另外一个父类或接口中 又定义了一个同名的方法时
第一种情况:父类中定义了同名,同参数列表方法。
选择父类中的方法。如果一个父类提供了具体的实现,那么接口中具有相同名称和参数的默认方法会被忽略。
接口中定义默认方法
interface interface1{
default void method(){
System.out.println("Myinterface1");
}
}
父类中定义完全一致方法
class father{
public void method(){
System.out.println("father");
}
}
子类
class son1 extends father implements interface1{
}
测试
public void test1() {
son1 Son1 = new son1();
Son1.method();
}
father
注意:如果希望父类中的方法能使接口中默认方法被隐藏,则父类方法访问权限必须是public
第二种情况:在另一个接口中定义了完全一致的方法
接口1中定义默认方法
interface interface1{
default void method(){
System.out.println("Myinterface1");
}
}
接口2中定义默认方法
interface interface2{
default void method(){
System.out.println("Myinterface2");
}
}
类声明接口
此时必须要显示的表明选择的是哪一个方法。同过在类中重写接口中方法的方式来选择用哪一个接口中的方法.否则编译会报错
class test implements interface1,interface2{
@override
public void method(){
interface1.super.method();
}
}
测试
public void test1() {
test Test = new test();
Test.method();
}
Myinterface1