接口(interface)主要用来描述类具有什么功能,但不需要给出各个功能的具体实现。
举个栗子:定义一个名为Person 人的接口,接口声明act() 动方法,人会动,但我们不知道人会怎么动,不同状态的人动作不一样。不同状态的人怎么动,就看实现Person接口的不同人的类如何实现这个方法。
public interface Person{ void act(); }
一个类可以实现(implements)一个或者多个接口。
接口可以继承接口,甚至能继承多个接口——接口的多继承。
接口中的所有方法都自动属于public,因此在接口中声明的方法,不必用public来修饰,不过你非要用public来修饰也不是不可以。
在JDK8以后可以在接口中实现一个或多个static或default修饰的方法。
例如在上面的Person接口中增加两个方法实现:
public interface Person{ void act();//相当于public abstract void act(); /* * 默认方法 * 有的人不需要工作或赚钱,所以此方法可以让实现类的对象选择性调用,或者根据需求overrid此方法 */ default String work(){ return "money"; } static void sleep(){ System.out.println("zzz"); } }
default修饰的方法work()能被接口Person的实现类所继承,在子类的的实例化对象中调用;
static修饰的方法sleep(),是类方法,调用方式和普通类方法相同,即用Person.sleep();
调用
在JDK9以后接口还支持用private修饰非抽象方法,即私有方法和私有类方法 。
其中,私有方法供接口中非static修饰的非抽象方法调用,私有类方法可供接口中所有非抽象方法调用。
接口中不能包含实例域,但是能包含static常量。
与接口中的方法都自动地被设置为 public—样,接口中的域都将被自动设为public static final 。
例如:在Person接口中增加一个常量MAX_AGE=130
public interface Person{ int MAX_AGE=130;//等同于public static final int MAX_AGE=130; void act(); }
首先,一个类只能继承一个抽象类,但是一个类可以实现多个接口。
其次,一个抽象类可以通过实例变量(字段)保存一个通用状态,而接口是不能有实例变量的。
例如上文例子中的work()方法,若该方法是抽象方法,那么实现Person的类,就必须实现该方法,哪怕该类用不到该方法。可若该方法是default默认方法,它会自动被实现类继承,实现类需要时调用,用不到不调用即可,而不用在实现类里写一个work()的空方法。
通过实现多个接口或者实现一个多继承接口,从而使得实现类获得重用多个接口默认方法的能力。
多方法的组合
public interface Person{ void sleep(); void work(); //定义一个摸鱼的默认方法,将工作和睡觉组合,这样所有人都get到了摸鱼技能了 default void moyu(){ work(); sleep(); } }
我们知道 Java 语言中一个类只能继承一个父类,但是一个类可以实现多个接口。随着默认方法在 Java 8 中引入,有可能出现一个类继承了多个方法但它们使用的是同样的函数签名。这种情况下,类会选择使用哪一个函数?Java解决这种冲突遵循以下三条规则:
public interface A{ default void hello(){ System.out.println("Hello from A"); } } public interface B extends A{ default void hello(){ System.out.println("Hello from B"); } } public class C implements B,A{ public static void main(String[] args) { new C().hello();//猜猜这里打印输出的是什么? } }
摘自《Java实战》 ↩︎
摘自《Java实战》 ↩︎