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

1. 接口的本质是什么?

答:接口是一种能力,很多时候反映的是对象以及对对象操作的本质

2. 定义接口的格式?

答:

  • interface 这个关键字声明接口,修饰符一般都是 public
  • 没有定义方法体,Java 8之前,接口内不能实现方法
  • 接口方法不需要加修饰符,加与不加都相当于 public abstract
  • 定义一个接口本身并没有做什么,也没有太大的用处,它还需要至少两个参与者:一个需要实现接口,另一个使用接口
  • 类可以实现接口,表示类的对象具有接口所表示的能力。

3. 使用接口的格式?

答:

  • 接口不能 new,不能直接创建一个接口对象,对象只能通过类来创建
  • 可以声明接口类型的变量,引用实现了接口的类对象

4. 针对接口编程的好处是?

答:代码复用,降低耦合,提高灵活性。

5. 接口的几个小细节?

答:

  • 接口中的变量。接口中可以定义变量,修饰符是 public static final,但这个修饰符是可选的,即使不写,也是 public static final,通过接口名.变量名访问变量。
  • 接口的继承。接口也可以继承,和类一样的是,关键字也是 extends;和类不同的是,接口可以有多个父接口,即 public interface IChild extends IBase1, IBase2 {} 的写法是合法的。
  • 类的继承与接口。类的继承与接口可以共存,需要注意的是关键字 extends 要放在 implements 之前。
  • instanceof。与类一样,接口也可以使用 instanceof 关键字,用来判断一个对象是否实现了某接口

6. 怎么理解使用组合和接口替代继承?

答:

  • 继承至少有两个好处:一个是复用代码;另一个是利用多态和动态绑定统一处理多种不同子类的对象。
  • 使用组合替代继承,可以复用代码,但不能统一处理。
  • 使用接口替代继承,针对接口编程,可以实现统一处理不同类型的对象,但接口没有代码实现,无法复用代码。
  • 将组合和接口结合起来替代继承,就既可以统一处理,又可以复用代码了。

7. Java 8Java 9 对接口做了哪些增强?

答:

  • Java 8 之前,接口中的方法都是抽象方法,都没有实现体
  • Java 8 允许在接口中定义两类新方法:静态方法和默认方法,它们有实现体
  • 示例:

    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 默认方法,定义为:

    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 默认方法,其定义为:

    default Stream<E> stream() {
        return StreamSupport.stream(spliterator(), false);
    }
    
-------------本文结束感谢您的阅读-------------