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

一. 接口默认方法

1. 定义

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

2. 特点

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

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

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

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

3. 举例

 1 package com.test.a;
 2 
 3 public interface Base {
 4     public default void f() {// only public,default,abstract
 5         System.out.println("hello world1");
 6     }
 7 
 8     default void f2() {
 9         System.out.println("hello world2");
10     }
11 
12     public void f3();;// 必须不能有方法体
13 
14     public static void f4() {// 必须要有方法体,即使方法体中没有具体的实现逻辑
15         System.out.println("hello world4");
16     }
17 
18 }
View Code
 1 package com.test.a;
 2 
 3 public class Sub implements Base {
 4 
 5     @Override
 6     public void f3() {
 7         System.out.println("hello world3");
 8 
 9     }
10     
11     public void f2() {//只可以时public,因为父类是public,子类不可以缩小父类的访问权限
12         System.out.println("hahahh");
13     }
14 
15 }
View Code
 1 package com.test.a;
 2 
 3 public class Test {
 4 
 5     public static void main(String args[]) {
 6         Sub sub = new Sub();
 7         sub.f();
 8         sub.f2();
 9         sub.f3();
10         Base.f4();// f4只可以Base来调用
11 
12     }
13 }
View Code
1 hello world1
2 hahahh
3 hello world3
4 hello world4
View Code

4. 为什么引入default方法?

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

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

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

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

5. 易错点

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

 1 public interface Base {
 2     public default void f() {// only public,default,abstract
 3         System.out.println("hello world1");
 4     }
 5 
 6     default void f2() {
 7         System.out.println("hello world2");
 8     }
 9 
10     public void f3();;// 必须不能有方法体
11 
12     public static void f4() {// 必须要有方法体,即使方法体中没有具体的实现逻辑
13         System.out.println("hello world4");
14     }
15 
16 }
17 
18 package com.test.a;
19 
20 public interface Base2 {
21     default void f2() {
22         System.out.println("Base2 hello world2");
23     }
24 
25 }
View Code

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

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

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

 1 package com.test.a;
 2 
 3 public interface Base {
 4     public default void f() {// only public,default,abstract
 5         System.out.println("hello world1");
 6     }
 7 
 8     default void f2() {
 9         System.out.println("hello world2");
10     }
11 
12     public void f3();;// 必须不能有方法体
13 
14     public static void f4() {// 必须要有方法体,即使方法体中没有具体的实现逻辑
15         System.out.println("hello world4");
16     }
17 
18 }
19 
20 package com.test.a;
21 
22 public class Sub implements Base {
23 
24     @Override
25     public void f3() {
26         System.out.println("hello world3");
27 
28     }
29 
30     public void f2() {
31         Base.super.f2();
32     }
33 
34 }
View Code
1 hello world1
2 hello world2
3 hello world3
4 hello world4
View Code

二. 静态方法

1. 定义

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

2. 特点

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

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

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

3. 用途

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

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

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

原文地址:https://www.cnblogs.com/Hermioner/p/9660383.html