接口是一组方法的定义和常量的集合。接口中定义的成员变量相当于最终变量,定义的方法相当于抽象方法。JDK-8之后可以在接口中定义带有方法体的方法。JDK-9之后可以在接口中定义私有方法。
一个类实现一个接口,必须实现该接口定义的所有方法。抽象类可以选择性实现接口方法,但是继承该抽象类的类也必须实现剩下未实现的接口方法。
与抽象类类似,接口也不能直接使用new运算实例化。需要有一个子类实现该接口并重写抽象方法,然后使用new运算调用子类构造方法实例化。
接口声明部分
一般的接口声明格式为:[public ][abstract ]interface 接口名[ extends 父接口名]
访问限制符:public属于访问限制符。没有被访问限制符修饰的接口只能在当前包内被调用。
public:被public修饰的接口是一个公共接口。可以被任意类或对象调用。每个Java源文件只能有一个public修饰的接口。
abstract:接口可以被abstract修饰,但是无实际意义。
extends:继承其他接口。每一个接口可以继承多个接口。
接口体部分
接口体部分包括了成员变量和方法的定义。
成员变量
一般的成员变量声明格式为:[public ][static ][final ]类型 变量名
接口中成员变量都隐含声明为public、static、final,所以在声明成员变量时加修饰符无实际意义。
方法
一般的方法声明格式为:[public ][abstract ]返回值类型 方法名(参数);
接口中定义的方法都隐含声明为public、abstract,所以在声明变量时加修饰符无实际意义。
带有方法体的方法
JDK-8之后可以在接口中定义带有方法体的方法。
带有方法体的方法分为2种:
默认方法:默认方法可以被重写,但是必须通过对象名调用。默认方法可以调用接口中定义的默认方法和静态方法。
静态方法:静态方法可以通过接口名调用,但是不可以被重写。静态方法只能调用接口中定义的静态方法。
一般的带有方法体的方法声明格式为:[public ]default | static 返回值类型 方法名(参数)
public:带有方法体的方法都隐含声明为public,所以再用public修饰无实际意义。
default:被default修饰的方法是默认方法。
static:被static修饰的方法是静态方法。
私有方法
JDK-9之后可以在接口中定义私有方法。私有方法不可以被重写,只能在接口内被调用。
私有方法分为私有默认方法和私有静态方法两种,分别对应默认方法和静态方法。
一般的私有方法声明格式为:private [static ]返回值类型 方法名(参数)
private:被private修饰的方法是私有方法。
static:被static修饰的方法是私有静态方法。没有被static修饰的方法是私有默认方法。
示例
1 interface If { 2 3 // 成员变量 4 int i = 1; 5 6 // 接口方法 7 void m1(); 8 9 // 默认方法 10 default void m2() { 11 System.out.println("默认方法......"); 12 System.out.println("调用m4():"); 13 m4(); // 调用私有默认方法 14 System.out.println("调用m5():"); 15 m5(); // 调用私有静态方法 16 } 17 18 // 静态方法 19 static void m3() { 20 System.out.println("静态方法......"); 21 System.out.println("调用m5():"); 22 m5(); // 调用私有静态方法 23 } 24 25 // 私有默认方法 26 private void m4() { 27 System.out.println("私有默认方法......"); 28 } 29 30 // 私有静态方法 31 private static void m5() { 32 System.out.println("私有静态方法......"); 33 } 34 35 }
1 class Impl implements If { 2 3 @Override 4 public void m1() { 5 System.out.println("访问接口中的i:" + i); 6 System.out.println("调用接口中的m2():"); 7 m2(); // 调用默认方法 8 } 9 10 // 重写接口中的默认方法 11 @Override 12 public void m2() { 13 If.super.m2(); 14 } 15 16 }
1 @Test 2 void test() { 3 System.out.println(If.i); // 访问接口中的成员变量 4 If impl = new Impl(); 5 impl.m1(); // 调用实现类重写的方法 6 impl.m2(); // 调用实现类重写的默认方法 7 If.m3(); // 调用接口中的静态方法 8 }
运行结果:
总结:
接口:
1.接口中的默认方法可以调用默认方法和静态方法。
2.接口中的静态方法可以调用静态方法。
3.接口中的私有方法只能在接口中调用。
实现类:
1.实现类可以直接访问接口的成员变量,直接调用接口的默认方法.
2.实现类需要重写接口中定义的接口方法。
3.实现类可以重写接口中的默认方法。
4.实现类可以通过“接口名.super.默认方法(参数)”来调用父接口的默认方法。
5.实现类无法重写接口中的静态方法。
外部:
1.外部可以通过接口名访问接口的成员变量,调用接口的静态方法。
2.外部可以通过实现类的实例调用接口的默认方法和实现类重写的接口方法。