0%

Java 类的扩展(一):接口的本质

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
    9
    public 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
    10
    default 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
    3
    default Stream<E> stream() {
    return StreamSupport.stream(spliterator(), false);
    }
-------------------- 本文结束感谢您的阅读 --------------------