Java8的新特性--接口中的默认方法与静态方法


接口中的默认方法与静态方法

写在前面

在Java8之前,接口没有任何具体的实现。

《JAVA编程思想》中是这样描述的:“interface这个关键字产生了一个完全抽象的类,它根本就没有提供任何具体的实现。它允许创建者确定方法名、参数列表和返回类型,但是没有任何方法体。接口只提供一种形式,而为提供任何具体的实现”。

但是在Java8中,对接口做了很大的的改动,接口中允许定义默认方法和静态方法了。

默认方法

以前接口中只能有全局静态常量和抽象方法,现在Java8的接口中可以拥有实现的方法了即默认方法。

接口的默认方法有助于在扩展系统功能的同时,不对现有的继承关系以及类库产生很大影响。比如,在JDK1.8中,Java集合框架的Collection接口增加了stream()等默认方法,这些默认方法即增强了集合的功能,又能保证对低版本的JDK的兼容。

下面为Collection接口的stream()方法源码:
默认方法

接口默认方法的语法:

default 关键字 methodName(参数列表) {//要实现的方法体}

在Java8中,因为存在函数式接口,一个接口中只能存在一个普通方法,但是可以写多个默认方法,来为实现类提供方法实现。

public interface MyInterface {
    //默认方法
    default String getName(){
        return "张三";
    }

    //默认方法
    default Integer getAge(){
        return 18;
    }

    //普通方法
    String getSomething();
}

既然接口中可以方法的实现,那么就会出现与父类之间进行冲突的问题。

public class MyClass {

    //默认方法
    public String getName(){
        return "李四";
    }
}

上面类中也有一个getName()方法,如果有一个类即实现了MyInterface接口又继承了MyClass类,我们想一下,这时候getName()方法是使用接口中的还是父类中的呢?

public class TestDefaultMethod extends MyClass implements MyInterface {

    @Override
    public String getSomething() {
        return null;
    }

    public static void main(String[] args) {
        TestDefaultMethod tfm = new TestDefaultMethod();
        System.out.println( tfm.getName());//打印输出了李四,说明调用的是父类的方法
    }
}

运行结果说明调用的是父类的方法。这里有一个类优先原则。

什么是“类优先”原则呢?若一个接口中定义了一个默认方法,而另一个父类又定义了一个同名的方法时,则优先调用父类的方法。

如果我们再定义一个接口,里面也有一个方法叫做getName,而一个类去同时实现这两个接口。那么这个类的 getName 方法到底会执行哪一个呢?

public interface MyInterface2 {
    //默认方法
    default String getName(){
        return "张三2";
    }

}
public class TestDefaultMethod2  implements MyInterface, MyInterface2 {

    //同名方法的接口要求我们必须重写,不重写就会报错了
    @Override
    public String getName() {
        return MyInterface2.super.getName();
    }

    //普通方法
    @Override
    public String getSomething() {
        return null;
    }

    public static void main(String[] args) {
        TestDefaultMethod2 tfm2 = new TestDefaultMethod2();
        System.out.println(tfm2.getName());//打印输出了李四,说明调用的是父类的方法
    }

}

此时,类会让我们自己去重写,自己去选择使用上面2个接口中的方法。

若一个接口中定义了一个默认方法,而另外一个接口中又定义了一个同名方法时,就会发生接口冲突。不管是否是默认方法,那么必须覆盖该方法来解决冲突。

静态方法

在Java 8中,接口中还允许添加静态方法

MyInterface接口中加一个静态方法

public interface MyInterface {
    //默认方法
    default String getName(){
        return "张三";
    }

    //静态方法
    public static void method(){
        System.out.println("这个是静态方法");
    }

    //普通方法
    String getSomething();


    public static void method(){
        System.out.println("这个是静态方法");
    }
}

测试静态方法的调用

public class TestMe {
    public static void main(String[] args) {
        //父接口.方法这种格式调用
        MyInterface.method();//打印输出  这个是静态方法
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值