一、概念
在Java中,接口是一种定义行为和功能规范的机制,它完全由抽象方法和常量组成。接口可以被视为一种契约,规定了一组方法的签名,任何实现该接口的类都必须提供这些方法的具体实现。从Java 8开始,接口可以包含默认方法(有实现的方法)和静态方法。
接口是Java中实现多态的一种方式,使得不同类可以以一致的方式进行交互,同时也提供了代码的复用性和扩展性。通过接口,你可以定义一系列类应遵守的协议,而不关心它们具体的实现细节。
二、接口特性
- 接口是隐式抽象的,当声明一个接口的时候,不必使用
abstract
关键字。 - 接口中每一个方法也是隐式抽象的,接口中的方法会被隐式的指定为
public abstract
(只能是 public abstract,其他修饰符都会报错)。 - 接口中可以含有变量,但是接口中的变量会被隐式的指定为
public static final
变量(并且只能是 public,用 private 修饰会报编译错误)。
三、接口语法
public interface MyInterface {
// 常量声明
int MAX_SPEED = 200; // 默认是 public static final
// 抽象方法声明
void drive();
// 默认方法(Java 8及以上版本)
default void stop() {
System.out.println("刹车...");
}
// 静态方法(Java 8及以上版本)
static void printMaxSpeed() {
System.out.println("最大速度: " + MAX_SPEED);
}
}
四、实现接口
类实现接口使用 implements
关键字,必须实现接口中所有的抽象方法。如果类是抽象的,则不需要实现所有的抽象方法。
public class Car implements MyInterface {
@Override
public void drive() {
System.out.println("开车...");
}
}
五、继承接口
接口可以继承其他接口,使用 extends
关键字。一个接口可以继承多个其他接口,这提供了多继承的能力,因为在Java中,类只能单继承。
public interface Vehicle extends MyInterface {
void accelerate();
}
六、多重实现接口
一个类可以实现多个接口,只需在 implements
关键字后列出所有接口即可。
public class SportsCar implements MyInterface, Vehicle {
@Override
public void drive() {
System.out.println("开车...");
}
@Override
public void accelerate() {
System.out.println("加速...");
}
}
七、接口和抽象类的区别
在Java中,接口和抽象类都可以用来实现抽象和多态,但它们之间存在一些关键的区别。以下是它们的主要区别:
方法实现
- 接口:接口中的所有方法默认情况下是抽象的,即没有方法体。从Java 8开始,接口可以包含默认方法(default关键字)和静态方法(static关键字),这些方法有具体实现。
- 抽象类:抽象类可以包含抽象方法和具体实现的方法。这意味着抽象类可以提供部分方法的默认行为。
继承限制
- 接口:可以实现多个接口,即Java中的多重继承可以通过接口来实现。
- 抽象类:只能继承一个抽象类,即Java中的类遵循单一继承原则。
成员变量
- 接口:接口中的成员变量默认是public static final的,通常用于常量。
- 抽象类:抽象类可以包含各种类型的成员变量,包括实例变量和静态变量。
构造方法
- 接口:接口中不允许有构造方法。
- 抽象类:抽象类可以有构造方法,用于初始化子类的共享状态。
访问修饰符
- 接口: 接口中的方法默认是public的。
- 抽象类: 抽象类中的方法可以有不同的访问修饰符。
实现要求
- 接口: 实现接口的类必须实现接口中所有的抽象方法,除非该类也是抽象的。
- 抽象类: 继承抽象类的子类可以选择性地实现抽象方法,也可以自己声明为抽象类而不实现这些方法。
设计用途
- 接口: 主要用于定义行为标准,即“做什么”。接口通常用于实现多态和定义对象之间的通信协议。
- 抽象类: 更多地用于提供一个基类,即“是什么”。抽象类可以提供一些共通的行为和状态,以及未完成的抽象方法供子类实现。