1. 接口的本质是什么
- 接口是一种能力,很多时候反映的是对象以及对对象操作的本质
2. 定义接口的格式
- 用
interface
这个关键字声明接口 - 修饰符一般都是
public
,接口方法不需要加修饰符,加与不加都相当于public abstract
。没有定义方法体,Java 8之前,接口内不能实现方法 - 定义接口本身并没有做什么,也没有太大的用处,它还需要至少两个参与者:一个需要实现接口,另一个使用接口。类可以实现接口,表示类的对象具有接口所表示的能力
3. 使用接口的格式
- 接口不能
new
,不能直接创建一个接口对象,对象只能通过类来创建 - 可以声明接口类型的变量,引用实现了接口的类对象
4. 针对接口编程的好处是
- 代码复用,降低耦合,提高灵活性
5. 接口的几个小细节
- 接口中的变量。接口中可以定义变量,只能是静态变量,不能是实例变量,修饰符是
public static final
,但这个修饰符是可选的,即使不写,也是public static final
,通过接口名.变量名访问变量 - 接口的继承。接口也可以继承,和类一样的是,关键字也是
extends
;和类不同的是,接口可以有多个父接口,即public interface IChild extends IBase1, IBase2 {}
的写法是合法的 - 类的继承与接口。类的继承与接口可以共存,需要注意的是关键字
extends
要放在implements
之前 instanceof
。与类一样,接口也可以使用instanceof
关键字,用来判断一个对象是否实现了某接口
6. 怎么理解使用组合和接口替代继承
- 继承至少有两个好处:一个是复用代码;另一个是利用多态和动态绑定统一处理多种不同子类的对象
- 使用组合替代继承,可以复用代码,但不能统一处理
- 使用接口替代继承,针对接口编程,可以实现统一处理不同类型的对象,但接口没有代码实现,无法复用代码
- 将组合和接口结合起来替代继承,就既可以统一处理,又可以复用代码了
7. Java 8 和 Java 9 对接口做了哪些增强
Java 8 之前,接口中的方法都是抽象方法,都没有实现体
Java 8 允许在接口中定义两类新方法:静态方法和默认方法,它们有实现体。示例:
1
2
3
4
5
6
7
8
9public interface IDemo {
void hello();
public static void test() {
System.out.println("hello");
}
default void hi() {
System.out.println("hi");
}
}- 静态方法
test()
可以通过IDemo.test()
调用 - 默认方法用关键字
default
修饰。默认方法有默认的实现,实现类可以改变它的默认实现,也可以不改变
- 静态方法
Java 8 中,静态方法和默认方法都必须是
public
的;Java 9 去除了这个限制,它们都可以是private
的,引入private
方法主要是为了方便多个静态或默认方法复用代码
8. Java 8 引入默认方法的原因是
- 引入默认方法主要是函数式数据处理的需求,是为了便于给接口增加功能
- 在没有默认方法之前,Java 是很难给接口增加功能的。比如
List
接口,因为有太多非 Java JDK 控制的代码实现了该接口,如果给接口增加一个方法,则那些接口的实现就无法在新版 Java 上运行,必须改写代码实现新的方法,这显然是无法接受的 - 函数式数据处理需要给一些接口增加一些新的方法,所以就有了默认方法的概念,接口增加了新方法,而接口现有的实现类也不需要必须实现
9. 接口增加默认方法的示例
List
接口增加了sort
默认方法,其实现为:1
2
3
4
5
6
7
8
9
10default void sort(Comparator<? super E> c) {
Object[] a = this.toArray();
Arrays.sort(a, (Comparator) c);
ListIterator<E> i = this.listIterator();
for(Object e : a) {
i.next();
i.set((E) e);
}
}Collection
接口增加了stream
默认方法,其定义为:1
2
3default Stream<E> stream() {
return StreamSupport.stream(spliterator(), false);
}