接口

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 {
       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.默认方法冲突

 如果先在一个接口中将一个方法定义默认方法,然后又在超类另一个接口定义了同样的方法,会发生什么情况?

规则如下

  1. 超类优先:如果超类(extends)提供了一个具体方法同名而且有相同参数类型的默认方法会被忽略
  2. 接口冲突:如果一个超接口(impelment)提供了一个默认方法另一个接口提供了一个同名而且参数类型相同方法,必须覆盖这个方法来解决冲突。如果其中一个默认方法并没有实现,由于Java更强调一致性,也需要重新覆盖方法

你可能感兴趣的:(接口)