天天看点

Java8 新特性 默认方法

默认方法为什么出现

默认方法的出现是因为在java8设计的过程中,因为加入了Lamdba表达式,和函数式接口,所以在非常多的接口里面要加入新的方法,但是如果在接口里面直接加入新的方法,那么以前写的所有的当前接口的现在类,全部都要加上新的实现。那么这对以前等于说就不兼容了,所以当时就产生了默认方法(Default Methods),默认方法就是为了解决这个问题的。

默认方法是什么

  默认方法就是接口里面可以有实现的方法,并且不需要实现类去实现其方法。并且默认方法允许你添加新的方法到现在的接口中,并且确保与旧版本的兼容性。

默认方法怎么用

  默认方法就是在接口签名前面加入default关键字就是默认方法了。

一个简单的小例子

public interface Test {
    default void sout() {
        System.out.println("调用Test里面的默认方法!");
    }
}
           
  • 实现类自动继承接口的默认方法,并且不用实现默认方法,就可以直接调用
public class TestDefaultMethod{
    public static void main(String[] args) {
        test1 test1 = new test1();
        test1.sout();
    }
}
class test1 implements Test{
}
           
输出:调用Test里面的默认方法!
           
  • 默认方法也可以重写
class test1 implements Test{
    @Override
    public void sout() {
        System.out.println("默认方法也可以继承!");
    }
}
           

并且就像你用List集合的Foreach方法一样,也是Iterable里面的默认方法,List集合就可以直接调用而不用自己实现。

//Iterable类里面的默认方法
default void forEach(Consumer<? super T> action) {
    Objects.requireNonNull(action);
    for (T t : this) {
        action.accept(t);
    }
}
           
//集合直接调用,并且List里面并没有这个方法,他是继承自Iterable类的
list.forEach(System.out::println);
           
  • 实现多个接口的时候,且有相同方法的调用问题的解决
public class TestDefaultMethod {
    public static void main(String[] args) {
        IntTest test = new test();
        test.sout();
    }
}

interface IntTest {
    default void sout() {
        System.out.println("调用Test里面的默认方法!");
    }

    static void syso() {
        System.out.println("调用Test里面的静态方法!");
    }
}

interface IntTest2 {
    default void sout() {
        System.out.println("调用Test2里面的默认方法!");
    }
}

class test implements IntTest, IntTest2 {

    public void sout() {
        IntTest2.super.sout();
        IntTest.super.sout();
        IntTest.syso();
        System.out.println("本方法里面的输出!");
    }
}
           

  可以看一下,这里面有两个接口,并且两个接口中都有sout方法,然后test把两个都实现了,但是如果只调用一个方法,会报错,所以想要调用接口里面的默认方法就可以用接口名.super.方法名。用这个方法不会出现冲突。

  并且上面还有一个新特性,接口可以声明静态方法 并且有实现类。

  上面的代码中已经用到了:

static void syso() {
    System.out.println("调用Test里面的静态方法!");
}
           
  • 还有就是接口和抽象类的比较
这里有一个更加好的抽象类和接口的比较 https://www.cnblogs.com/sidesky/p/9287710.html

下面是接口和实现类的对比:

1、接口可以被类多实现(被其他接口多继承),抽象类只能被单继承。
2、接口中没有 this指针,没有构造函数,不能拥有实例字段(实例变量)或实例方法,无法保存 状态(state),抽象方法中可以。
3、抽象类不能在 java 8 的 lambda 表达式中使用。
4、从设计理念上,接口反映的是 “like-a” 关系,抽象类反映的是 “is-a” 关系。
           

本篇文章的引用:

Java 8 (8) 默认方法

Java 8 默认方法(Default Methods)

Java 8 默认方法(菜鸟教程)

我的公众号

细节决定成败!

个人愚见,如有不对,恳请斧正!