1.接口基础知识
接口技术主要用来描述类具有什么功能,而并不给出每个功能的具体实现。一个类可以实现(implement)一个或多个接口。
在Java程序设计语言中,接口不是类,而是对类的一组需求描述,这些类要遵从接口描述的统一格式进行定义。
接口中所有的方法自动地属于public。因此,在接口中声明方法时,不必提供关键字public。
为了让类实现一个接口,通常需要下面两个步骤:
- 将类声明为实现给定的接口。
- 对接口中所有的方法进行定义。
2.接口特性
接口不是类,不能使用new运算符实例化一个接口。接口变量必须引用实现了接口的类对象。
Comparable x = new Employee(...);
接口可以被扩展。接口中不能包含实例域或静态方法(在Java SE8中允许在接口中增加静态方法),但是却可以包含常量。接口中的域都被自动设为public static final。
public interface Moveable {
void move(double x, double y);
}
public interface Powered extends Moveable {
double milesPerGallon();
double SPEED_LIMIT = 95;
}
每一个类值能够拥有一个超类,但却可以实现多个接口。
3.默认方法
可以为接口提供一个默认实现,必须用default修饰符标记这样一个方法(在Java SE8中可以把所有的方法声明为默认方法)。
默认方法可以调用接口内任何其他方法。这样一来,实现接口时,只需要关心真正需要的实现的方法即可。
public interface Comparable<T> {
default int comparaTo(T other) {return 0;}
}
public interface Text {
int size();
default boolean isEmpty() {
return size() == 0;
}
}
默认方法的一个重要用法是“接口演化”。以Collection接口为例,这个接口作为java的一部分已经有很多年了。假设在很久以前提供了这样一个类:
public class Bag implements Collection
后来在Java SE8中,又为这个接口增加了一个stream方法。假设stream方法不是一个默认方法,那么Bag类将不能编译,因为它没有实现这个新方法。为接口增加一个非默认方法不能保证“源代码兼容”。
不过,假设不重新编译这个类,而只是使用原先的一个包含这个类的JAR文件。这个类仍能正常加载,尽管没有这个新方法。程序仍然可以正常构造Bag实例,不会又意外发生。但是,如果程序在一个Bag实例上调用stream方法,就会出现异常错误。
将stream方法实现为一个默认方法就可以解决上面的两个问题。Bag类可以正常编译。如果没有重新编译而直接加载这个类,并在一个Bag实例上调用stream方法,将调用Collection.stream方法。
4.默认方法冲突
如果先在一个接口中将一个方法定义为默认方法,然后又在超类或另一个接口中定义了同样的方法,会发生什么情况?
规则如下:
- 超类优先:如果超类(extends)提供了一个具体方法,同名而且有相同参数类型的默认方法会被忽略。
- 接口冲突:如果一个超接口(impelment)提供了一个默认方法,另一个接口提供了一个同名而且参数类型相同的方法,必须覆盖这个方法来解决冲突。如果其中一个默认方法并没有实现,由于Java更强调一致性,也需要重新覆盖方法。










网友评论