Java8特性之接口方法

标签: Java

保留所有版权,请引用而不是转载本文(原文地址 https://yeecode.top/blog/12/ )。

1 概述

Java 8由Oracle公司于2014年3月18日发布,至今已过去数年之久。然而,直到今日仍有许多软件开发者对其相关特性不了解,这可能主要是Java教材更新缓慢的原因。为了使大家对与Java8的特性有全面系统的了解,本公众号将连续几篇文章介绍Java8中的各个特性。

Java8中新增的特性主要有:

本文介绍其中的默认方法。其它特性会在后续文章中陆续介绍。

2 接口中含有方法实现

早期的Java版本的接口拥有非常的严格的接口,接口中只能有抽象方法,不能存在实现。抽象方法和实现方法混合的,那叫作抽象类。

而继承了接口的对象,必须要指定接口的实现。

2.1 默认方法

而Java8的新特性:接口中也可以有方法的默认实现。集成了接口的对象可以不指定默认方法的实现,而直接使用其默认实现。

我们展开讲一下:

public class TestBean {
    public static void main(String[] args) {
        Say say = new Say() {
            @Override
            public void sayHi(String name) {
                System.out.println("hei hei");
            }
        };
        say.sayHi("lilei");
        say.sayHelloWorld();
    }

    public interface Say {
        void sayHi(String name);
        default void sayHelloWorld() {
            System.out.println("hello world");
        }
    }
    
}

首先我们看一下Say接口,它本身有两个方法,一个抽象方法sayHi(String name),另外一个是带有默认实现的sayHelloWorld()。它本身有default关键字声明,然后可以写它默认的实现。

我们创建了一个匿名对象,必须给抽象方法指定实现,但是默认实现不需要指定,这样就会采用默认的实现方式。

这方面好的例子是大量的方法被添加到java.util.Collection接口中去:stream(),parallelStream(),forEach(),removeIf(),……

尽管默认方法非常强大,但是在使用默认方法时我们需要小心注意一个地方:在声明一个默认方法前,请仔细思考是不是真的有必要使用默认方法,因为默认方法会带给程序歧义,并且在复杂的继承体系中容易产生编译错误。

2.2 静态方法

Java 8带来的另一个有趣的特性是接口可以声明(并且可以提供实现)静态方法。

类似于类中的静态方法,接口定义的静态方法可以独立于任何对象调用。所以,在调用静态方法时,不需要实现接口,也不需要接口的实例,也就是说和调用类的静态方法的方式类似 : Interface.staticFun()

举例子,先定义一个接口:

public interface UserInterface {
    static void staticSayHi() {
        System.out.println("Hi, static function in interface.");
    }

    default void defaultSayHi() {
        System.out.println("Hi, default function in interface");
    }

    void normalSayHi();
}

然后定义一个对象:

public class UserBean implements UserInterface{
    @Override
    public void normalSayHi() {
        System.out.println("Hi, normal say hi!");
    }
}

调用如下:

public class TestBean {
    public static void main(String[] args) {
        UserBean userBean = new UserBean();
        userBean.normalSayHi(); // 只能用对象userBean访问
        userBean.defaultSayHi(); // 只能用对象userBean访问

        // staticSayHi作为接口的静态方法,无法使用UserBean类或者userBean对象引用到
        //  userBean.staticSayHi(); // 错误,调用不到
        
        // 需要使用接口引用
        UserInterface.staticSayHi(); // 只能用接口访问
    }
}

因此,接口的静态方法只能由接口来调用,它不属于实现了那个接口的对象,对象调用不到。

这时,我们想起了类的静态方法,那它也属于类,但是类的对象能调用到,但是IDEA会直接爆出警告,因此,虽然能调用到,但是极为不推荐。

3 总结

Java8 提供的接口中的默认方法为编程的灵活性注入了新活力。接口默认方法使得我们不必强制实现接口中的所有方法,能让程序更为简洁、清晰。

关于Java8中接口默认方法的介绍就到这里,在后续的文章中我们将介绍Java8中的其它特性。

本文首发于个人知乎:易哥(https://www.zhihu.com/people/yeecode),欢迎关注。

作者书籍推荐