Java8 为什么在接口中引入default方法?

Java8 之前,如果需要在一个已有的接口中添加一个方法,那么所有这个接口的实现类也都必须同时实现这个方法,否则程序将无法正常编译运行。

为了解决这一问题,Java8 在接口中引入了 default 方法。

default 方法也被称之为守护方法(defender method)或者虚拟扩展方法(virtual extension method)。可以在接口中包含一些默认的包含方法体的方法,从而使得接口在进行扩展的时候,不会破坏它的实现类,从而更好的实现开闭原则。


如何使用?


01

接口中定义default方法


使用default关键字在接口中定义default方法。

public interface Car {

    default boolean canFly(){
        return false;
    }
}


02

实现类不实现 default 方法


毕竟当前的汽车都不能飞的嘛,所以基本上实现类都可以不用管这个default方法。

public class MyCar implements Car {
    
    public static void main(String[] args) {
        MyCar myCar = new MyCar();
        System.out.println("我的车会飞吗?--> " + myCar.canFly());
    }
}

运行结果:调用接口中定义好的default方法。

我的车会飞吗?--> false


03

实现类实现 default 方法


假如哪一天有了可以飞的汽车,那么在实现类中实现这个default方法即可。

public class MyFlyCar implements Car {

    @Override
    public boolean canFly() {
        return true;
    }

    public static void main(String[] args) {
        MyFlyCar myCar = new MyFlyCar();
        System.out.println("我的车会飞吗?--> " + myCar.canFly());
    }
}
运行结果:调用实现类中的canFly方法。
我的车会飞吗?--> true


Java8 为什么在接口中引入default方法?


Java8 为什么在接口中引入default方法?

 同时实现具有相同default方法的两个接口会怎样?

Java8 为什么在接口中引入default方法?

编译报错,因为编译器不知道该使用哪个接口中的default方法,它们的优先级是一样的。解决方法是在实现类中实现该default方法,像MyFlyCar那样。

Java8 为什么在接口中引入default方法?

 具有default方法的接口和抽象类有啥区别?

Java8 为什么在接口中引入default方法?

1. 抽象类有构造器,接口没有。

2. 抽象类只能继承一个,而接口可以实现多个。

3. 抽象类的方法可以有publicprotected、缺省(没有修饰符) 和 private这些修饰符,但是接口方法默认修饰符都是public,即使default方法也不例外。

Java8 为什么在接口中引入default方法?

Java8 之前,接口方法默认都是 public abstract,即必须由实现类实现。 Java8 加入了public default,实现类可以不实现也可以实现。


Java8 除了在接口中新增了default 方法外,还新增了 static 方法。


Java9 又在接口中加入了 private 方法,主要用途就是将 default 方法中的公共部分抽出来。



在JDK中的使用

1.  java.util.Collection: 用于支持Stream的使用。
public interface Collection<E> extends Iterable<E> {

    /**
     * some other method
     */


    default <T> T[] toArray(IntFunction<T[]> generator) {
        return toArray(generator.apply(0));
    }

    default boolean removeIf(Predicate<? super E> filter) {
        Objects.requireNonNull(filter);
        boolean removed = false;
        final Iterator<E> each = iterator();
        while (each.hasNext()) {
            if (filter.test(each.next())) {
                each.remove();
                removed = true;
            }
        }
        return removed;
    }

    @Override
    default Spliterator<E> spliterator() {
        return Spliterators.spliterator(this, 0);
    }

    default Stream<E> stream() {
        return StreamSupport.stream(spliterator(), false);
    }


    default Stream<E> parallelStream() {
        return StreamSupport.stream(spliterator(), true);
    }
}

2.  java.util.Collection: 用于支持函数式编程。

public interface Iterable<T> {

    Iterator<T> iterator();

    default void forEach(Consumer<? super T> action) {
        Objects.requireNonNull(action);
        for (T t : this) {
            action.accept(t);
        }
    }
    default Spliterator<T> spliterator() {
        return Spliterators.spliteratorUnknownSize(iterator(), 0);
    }
}
Java8 为什么在接口中引入default方法?

点个在看你最好看

原文始发于微信公众号(i余数):Java8 为什么在接口中引入default方法?

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/194102.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!