Java 接口是一系列方法的声明,是一些方法特征的集合,一个接口只有方法的特征没有方法的实现,因此这些方法可以在不同的地方被不同的类实现,而这些实现可以具有不同的行为(功能)。
一个类通过继承接口的方式,从而来继承接口的抽象方法。除非实现接口的类是抽象类,否则该类需要实现接口中的所有方法。
接口无法被实例化,但是可以被实现。一个实现接口的类,必须实现接口内所描述的所有方法,否则就必须声明为抽象类。另外,在 Java 中,接口类型可用来声明一个变量,他们可以成为一个空指针,或是被绑定在一个以此接口实现的对象。
接口中每一个方法也是隐式抽象的,接口中的方法会被隐式的指定为 public abstract(只能是 public abstract,其他修饰符都会报错)。
接口中可以含有变量,但是接口中的变量会被隐式的指定为 public static final 变量(并且只能是 public,用 private 修饰会报编译错误)。
接口中的方法是不能在接口中实现的,只能由实现接口的类来实现接口中的方法。
(1)接口被用来描述一种抽象。
(2)因为 Java 不像 C++ 一样支持多继承,所以 Java 可以通过实现接口来弥补这个局限。
(3)接口也被用来实现解耦。
(4)接口被用来实现抽象,而抽象类也被用来实现抽象,为什么一定要用接口呢?接口和抽象类之间又有什么区别呢?原因是抽象类内部可能包含非 final 的变量,但是在接口中存在的变量一定是 final,public,static 的。
(1)抽象类中的方法可以有方法体,就是能实现方法的具体功能,但是接口中的方法不行。
(2)抽象类中的成员变量可以是各种类型的,而接口中的成员变量只能是 public static final 类型的。
(3)接口中不能含有静态代码块以及静态方法 (用 static 修饰的方法),而抽象类是可以有静态代码块和静态方法。
(4)一个类只能继承一个抽象类,而一个类却可以实现多个接口。
注意:
(1)JDK 1.8 以后,接口里可以有静态方法和方法体了。
(2)JDK 1.8 以后,接口允许包含具体实现的方法,该方法称为 “默认方法”,默认方法使用 default 关键字修饰。
(3)JDK 1.9 以后,允许将方法定义为 private,使得某些复用的代码不会把方法暴露出去。
在 Java 中,接口通常以 interface 关键字来声明。定义接口的基本语法如下:
[修饰符] interface 接口名 [extends 父接口名列表] { [public] [static] [final] 变量; [public] [abstract] 方法; }
说明:
修饰符:可选参数,用于指定接口的访问权限,可选值为 public。如果省略则使用默认的访问权限。
接口名:必选参数,用于指定接口的名称,接口名必须是合法的 Java 标识符。一般情况下,要求首字母大写。
extends 父接口名列表:可选参数,用于指定要定义的接口继承于哪个父接口。当使用 extends 关键字时,父接口名为必选参数。
方法:接口中的方法只有定义而没有被实现。
下面定义一个用于计算的接口,在该接口中定义一个常量 PI 和两个方法,分别计算面积和周长。代码如下:
/** * 圆计算接口 * @author hxstrive.com */ public interface ICircleCalculate { /** * 定义用于表示圆周率的常量 PI */ public final float PI = 3.14159f; /** * 定义一个用来计算面积的方法 * @param radius 半径 * @return */ public float getArea(float radius); /** * 定义一个用来计算周长的方法 * @param radius 半径 * @return */ public float getCircumference(float radius); }
接口在定义后,就可以在类中实现该接口。在类中实现接口可以使用 implements 关键字,基本语法如下:
[修饰符] class <类名> [extends 父类名] [implements 接口列表] { //... }
说明:
修饰符:可选参数,用于指定类的访问权限,可选值为 public、abstract 和 final。
类名:必选参数,用于指定类的名称,类名必须是合法的 Java 标识符。一般情况下,要求首字母大写。
extends 父类名:可选参数,用于指定要定义的类继承于哪个父类。当使用 extends 关键字时,父类名为必选参数。
implements 接口列表:可选参数,用于指定该类实现的是哪些接口。当使用 implements 关键字时,接口列表为必选参数。
注意:在类中实现接口时,方法名、返回值类型、参数的个数及类型必须与接口中的完全一致,并且必须实现接口中的所有方法。
编写一个名称为 Cire 的类,该类实现上面定义的 ICircleCalculate 接口,代码如下:
/** * 实现 ICircleCalculate 接口 * @author hxstrive.com */ public class Cire implements ICircleCalculate { /** * 实现接口的 getArea 方法 * @param radius 半径 * @return */ @Override public float getArea(float radius) { return PI * radius * radius; } /** * 实现接口的 getCircumference 方法 * @param radius 半径 * @return */ @Override public float getCircumference(float radius) { return PI * radius * 2; } public static void main(String[] args) { // 创建 Cire 类的对象,然后将 ICircleCalculate 类型的 cire 变量指向该对象 ICircleCalculate cire = new Cire(); // 获取圆的面积,半径为 5 System.out.println("圆面积:" + cire.getArea(5)); // 获取圆的周长,半径为 5 System.out.println("圆周长:" + cire.getCircumference(5)); } }
运行示例,输出如下:
圆面积:78.53975 圆周长:31.415901