一,接口定义
官方解释:Java接口是一系列方法的声明,是一些方法特征的集合,一个接口只有方法的特征没有方法的实现,因此这些方法可以在不同的地方被不同的类实现,而这些实现可以具有不同的行为(功能)。
在我看来,接口就是一个标准,可以看作一个抽象类,其中可以定义属性和方法。
接口的关键字是interface,接口定义的语法格式如下:
public interface <interface_name> {
// 接口体,其中可以包含定义常量和声明方法
[public] [static] [final] type constant_name = value; // 定义常量
[public] [abstract] returnType method_name(parameter_list); // 声明方法
}
具体举例如下:
public interface MyInterface {
// 接口MyInterface
String name; // 不合法,变量name必须初始化
int AGE = 20; // 合法,等同于 public static final int AGE = 20;
int getInfo(int i); // 方法声明,等同于 public abstract int getInfo(int i);
}
在接口中有这样一些规则:
- 属性默认为public static final类型的常量,命名一般使用全大写字母表达尽可能详细,并且属性必须初始化。
- 方法默认为public abstract类型,说明该方法是抽象的,没有具体的方法体,但是可以定义返回值类型和参数类型。
二,接口的实现
接口的主要作用是被类实现,一个类可以实现一个或多个接口,使用implements关键字,类实现接口的语法格式如下:
public class <class_name> implements <interface1_name[, interface2_name…]> {
// 主体
}
具体举例如下:
- 创建一个IMath的接口
public interface IMath {
public int sum(); // 完成两个数的相加
public int maxNum(int a,int b); // 获取较大的数
}
2,定义一个MathClass类并实现IMath接口
public class MathClass implements IMath {
private int num1; // 第 1 个操作数
private int num2; // 第 2 个操作数
public MathClass(int num1,int num2) {
// 构造方法
this.num1 = num1;
this.num2 = num2;
}
// 重写接口中的求和方法
public int sum() {
return num1 + num2;
}
// 重写接口中的获取较大数的方法
public int maxNum(int a,int b) {
if(a >= b) {
return a;
} else {
return b;
}
}
}
在类实现接口的时候,需要注意到:
(a)必须操作: 由于接口的方法是抽象方法,并没有具体的方法体,这个类必须完全实现这些接口里所定义的全部抽象方法(也就是重写这些抽象方法);否则,该类将保留从父接口那里继承到的抽象方法,该类也必须定义成抽象类。
(b)可选操作:实现接口的类可以直接使用接口中的静态常量。
3,最后创建测试类 NumTest,实例化接口的实现类 MathClass,调用该类中的方法并输出结果。

public class NumTest {
public static void main(String[] args) {
// 创建实现类的对象
MathClass calc = new MathClass(100, 300);
System.out.println("100 和 300 相加结果是:" + calc.sum());
System.out.println("100 比较 300,哪个大:" + calc.maxNum(100, 300));
}
}
输出结果如下:
100 和 300 相加结果是:400
100 比较 300,哪个大:300
在该测试类中我们注意到这样一行代码:
MathClass calc = new MathClass(100, 300);
该行代码的意思是创建了一个MathClass类型的calc对象,这里涉及到自动转型的问题。由于接口不是类,不能实例化,因此不能创建对象,所以我们要使用继承了接口的类来创建对象。有两种自动转型的方法:
假设类1继承了接口1
-
接口1类型 对象名 = new 类1名();
这种转型类1的对象不能调用自己的属性和方法,缺乏灵活性。 -
类1名 对象名 = new 类名1();
由于类1继承了接口1,创建的对象可以自动转型为接口类型,这样类1的对象不仅可以使用接口1的属性和方法,还可以使用自己的属性和方法,灵活性强。
三,接口的优点
- 简单、规范性:如果一个程序十分庞大,那么就需要一个可以理清所有思路的架构师来定义接口,在接口里规定了所有需要实现的功能以及命名规范,防止一些开发人员随便命名导致其他程序员无法看懂。
- 安全、严密性:接口里的方法没有具体的操作,描述了系统对外的服务,是实现软件松耦合的重要手段,这样安全、严密一点。
- 拓展性强,降低改变带来的影响,封装变化的部分:如果某天发现自己定义的类满足不了需求需要修改该类甚至放弃但是又在其他地方引用了该类的时候,这样处理起来会很麻烦。但是如果一开始定义了一个接口,把功能放在接口里时,使用两种类来实现该接口,这样可以增加新功能又不妨碍之前使用了旧功能的地方。