接口是类的抽象,没有实现细节。例如,java.lang.Comparable
是 Java 中的标准接口。你无法实例化接口。接口不是类,但它以相同的方式编写。第一个区别是,你不用 class
关键字,而是用 interface
关键字来定义它。然后,你不能在这里定义字段和方法
- 字段始终是常量:它始终是公共的、静态的和最终的,即使你没有提到它。
- 方法必须是公共的和抽象的,但不需要写
public
和 abstract
关键字。
- 构造函数是被禁止的。
接口代表一个契约
|
代码清单 4.14:SimpleInterface.java
public interface SimpleInterface {
public static final int CONSTANT1 = 1;
int method1(String parameter);
}
|
你可以看到 method1()
方法是抽象的(未实现)。要使用接口,你必须定义一个实现它的类,使用 implements
关键字
|
代码清单 4.15:ClassWithInterface.java
public class ClassWithInterface implements SimpleInterface {
public int method1(String parameter) {
return 0;
}
}
|
一个类可以实现多个接口,用逗号分隔。Java 接口的行为与 Objective-C 协议的概念非常相似。建议将接口命名为 <动词>able
,表示此接口将在类上启用的操作类型。但是,不建议在接口名称前面加上 I
,如 C++ 中那样。这没有用。你的 IDE 会为你提供帮助。
如果你有来自不同类且没有共同超类的对象,你无法在这些类中调用相同的方法,即使这两个类实现了具有相同签名的方法。
|
代码清单 4.16:OneClass.java
public class OneClass {
public int method1(String parameter) {
return 1;
}
}
|
|
代码清单 4.17:AnotherClass.java
public class AnotherClass {
public int method1(String parameter) {
return 2;
}
}
|
|
代码部分 4.16:无法调用。
public static void main(String[] args) {
doAction(new OneClass());
doAction(new AnotherClass());
}
public void doAction(Object anObject) {
anObject.method1("Hello!");
}
|
解决方法是编写一个定义应该在两个类中实现的方法的接口,如 代码清单 4.14 中的 SimpleInterface
,然后这两个类都可以实现接口,如 代码清单 4.15 中那样。
|
代码部分 4.17:接口使用。
public static void main(String[] args) {
doAction(new ClassWithInterface());
doAction(new AnotherClassWithInterface());
}
public void doAction(SimpleInterface anObject) {
anObject.method1("Hello!");
}
|
你也可以使用一个共同的超类来实现这一点,但一个类只能从一个超类继承,而它可以实现多个接口。
Java 不支持完全正交多重继承(即 Java 不允许你从两个类创建子类)。C++ 中的多重继承有复杂的规则来消除从多个超类继承的字段和方法以及多次继承的类型的歧义。通过将接口与实现分离,接口在复杂性和歧义性较小的情况下提供了多重继承的大部分优势。没有多重继承的代价是一些代码冗余;由于接口只定义类的签名,而不能包含任何实现,所以每个继承接口的类都必须提供定义方法的实现,不像纯粹的多重继承那样,实现也是继承的。这样做的主要好处是,所有 Java 对象都可以有一个共同的祖先(一个名为 Object
的类)。
在覆盖接口中定义的方法时,需要遵循一些规则
- 不应该在实现方法上声明受检异常,除了接口方法声明的异常或接口方法声明的异常的子类。
- 在实现方法时,应该保持接口方法的签名和相同的返回类型或子类型。
- 实现接口的类需要定义接口的所有方法,除非该类是抽象类。
接口可以扩展多个接口,类似于类可以扩展另一个类的方式,使用 extends
关键字
|
代码清单 4.18:InterfaceA.java
public interface InterfaceA {
public void methodA();
}
|
|
代码清单 4.19:InterfaceB.java
public interface InterfaceB {
public void methodB();
}
|
|
代码清单 4.20:InterfaceAB.java
public interface InterfaceAB extends InterfaceA, InterfaceB {
public void otherMethod();
}
|
这样,实现InterfaceAB
接口的类必须实现methodA()
、methodB()
和otherMethod()
方法。
|
代码清单 4.21:ClassAB.java
public class ClassAB implements InterfaceAB {
public void methodA() {
System.out.println("A");
}
public void methodB() {
System.out.println("B");
}
public void otherMethod() {
System.out.println("foo");
}
public static void main(String[] args) {
ClassAB classAb = new ClassAB();
classAb.methodA();
classAb.methodB();
classAb.otherMethod();
}
}
|
这样做,ClassAB
对象可以被强制转换为InterfaceA
、InterfaceB
和InterfaceAB
。