一. 接口默认方法
1. 定义
接口不只是一个只能声明方法的地方,还可以在声明方法的时候,给方法一个默认的实现,而不需要实现类去实现其方法。默认方法用default关键字修饰,它默认就是public权限的。
2. 特点
(1)所有的实现类都会自动继承接口中定义的默认方法;
(2)接口中的默认方法可以被实现类重写;
(3)在被调用时,实现类重写后的方法优先于默认方法;
(4)和1.8之前一样,在接口中仍然不允许定义普通的实现方法,接口任然会保持除这些新特性外的所有原有特性.
3. 举例
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 hello world1 2 hahahh 3 hello world3 4 hello world4
4. 为什么引入default方法?
(1)以前的接口中只要定义了方法,都需要在实现类中进行实现。即使是个空的实现,也必须写出来;但是在新特性中,添加了默认方法,就无需在实现类中再次实现了,除非想要再次实现,直接重写就可以了;
(2)为接口添加新的默认方法,是不会破坏原有接口的实现;
(3)不需要修改接口的实现类,就可以为接口添加新的方法实现;
(4)对于已经发布的版本,是无法在给接口添加新方法的同时而不影响已有的实现,因此引入了default。目的是为了解决接口的修改与已有的实现不兼容的问题。
5. 易错点
(1)如果一个类实现两个或两个以上接口,并且多个接口中包含统一默认方法,此时,编译器将报错。这种情况,我们必须让子类Override该方法,否则无法编译通过。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }
上面就会提示要么重写Base的f2方法,要么重写Base2的f2方法;
(2)如果是一个接口继承了另外一个接口,2个接口中也包含相同的默认方法,那么继承接口的版本具有更高的优先级。比如A继承了B接口,那么优先使用A接口里面的default方法;
(3)通过使用super,可以显式的引用被继承接口的默认实现,语法如下:InterfaceName.super.methodName()。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 hello world1 2 hello world2 3 hello world3 4 hello world4
二. 静态方法
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) 中的静态方法,进行调用;