Java8新特性 接口中允许有默认方法和静态方法

一、接口的默认方法

定义

接口不只是一个只能声明方法的地方,还可以在声明方法的时候,给方法一个默认的实现,而不需要实现类去实现其方法。默认方法用default关键字修饰,它默认就是public权限的。

特点

(1)所有的实现类都会自动继承接口中定义的默认方法;

(2)接口中的默认方法可以被实现类重写;

(3)在被调用时,实现类重写后的方法优先于默认方法;

(4)和1.8之前一样,在接口中仍然不允许定义普通的实现方法,接口任然会保持除这些新特性外的所有原有特性。

举例

package com.test.a;

public interface Base {
    public default void f() {// only public,default,abstract
        System.out.println("hello world1");
    }

    default void f2() {
        System.out.println("hello world2");
    }

    public void f3();;// 必须不能有方法体

    public static void f4() {// 必须要有方法体,即使方法体中没有具体的实现逻辑
        System.out.println("hello world4");
    }

}
package com.test.a;

public class Sub implements Base {

    @Override
    public void f3() {
        System.out.println("hello world3");

    }
    
    public void f2() {//只可以时public,因为父类是public,子类不可以缩小父类的访问权限
        System.out.println("hahahh");
    }

}
package com.test.a;

public class Test {

    public static void main(String args[]) {
        Sub sub = new Sub();
        sub.f();
        sub.f2();
        sub.f3();
        Base.f4();// f4只可以Base来调用

    }
}

1 hello world1
2 hahahh
3 hello world3
4 hello world4

为什么引入default方法?

(1)以前的接口中只要定义了方法,都需要在实现类中进行实现。即使是个空的实现,也必须写出来;但是在新特性中,添加了默认方法,就无需在实现类中再次实现了,除非想要再次实现,直接重写就可以了;

(2)为接口添加新的默认方法,是不会破坏原有接口的实现;

(3)不需要修改接口的实现类,就可以为接口添加新的方法实现;

(4)对于已经发布的版本,是无法在给接口添加新方法的同时而不影响已有的实现,因此引入了default。目的是为了解决接口的修改与已有的实现不兼容的问题。

5. 易错点

(1)如果一个类实现两个或两个以上接口,并且多个接口中包含统一默认方法,此时,编译器将报错。这种情况,我们必须让子类Override该方法,否则无法编译通过。

public interface Base {
    public default void f() {// only public,default,abstract
        System.out.println("hello world1");
    }

    default void f2() {
        System.out.println("hello world2");
    }

    public void f3();;// 必须不能有方法体

    public static void f4() {// 必须要有方法体,即使方法体中没有具体的实现逻辑
        System.out.println("hello world4");
    }

}

package com.test.a;

public interface Base2 {
    default void f2() {
        System.out.println("Base2 hello world2");
    }

}


上面就会提示要么重写Base的f2方法,要么重写Base2的f2方法;

(2)如果是一个接口继承了另外一个接口,2个接口中也包含相同的默认方法,那么继承接口的版本具有更高的优先级。比如A继承了B接口,那么优先使用A接口里面的default方法;

(3)通过使用super,可以显式的引用被继承接口的默认实现,语法如下:InterfaceName.super.methodName()。

package com.test.a;

public interface Base {
    public default void f() {// only public,default,abstract
        System.out.println("hello world1");
    }

    default void f2() {
        System.out.println("hello world2");
    }

    public void f3();;// 必须不能有方法体

    public static void f4() {// 必须要有方法体,即使方法体中没有具体的实现逻辑
        System.out.println("hello world4");
    }

}

package com.test.a;

public class Sub implements Base {

    @Override
    public void f3() {
        System.out.println("hello world3");

    }

    public void f2() {
        Base.super.f2();
    }

}

1 hello world1
2 hello world2
3 hello world3
4 hello world4

静态方法

定义

和普通的静态方法定义一样

特点

(1)只能是静态方法所属的类来调用(即使是子类等等都不行)

(2)**必须有方法体,**即使方法体中没有具体实现;区别于上面的普通方法必须不能有方法体;

(3)实现接口的类或者子接口不会继承接口中的静态方法。static不能和default同时使用。在java8中很多接口中都增加了静态方法

用途

(1)因为是静态方法,它是不能被实现类重写的(否则编译异常:This static method cannot hide the instance method from Object),因此,它可以用来提供防止实现类不良重写的保障;

(2)常常可以作为工具型的方法,比如:空值检查,集合类排序等等;

(3)比如可以将java.util.collections类改成接口(eg:Collection) 中的静态方法,进行调用;

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值