1. 接口的概念
在 Java 中,接口(Interface) 是一种完全抽象的类,它定义了一组行为规范,即类必须提供的功能。接口提供了多个类之间共享行为的方式,而不涉及具体的实现细节。通过接口,Java 支持多继承,一个类可以实现多个接口,从而同时提供多种行为。
接口的核心目的:
- 定义行为规范:接口仅仅定义方法,而不提供方法的实现,这使得不同类可以以不同的方式实现相同的行为。
- 实现解耦:接口和实现类之间的依赖较低,可以实现代码的松耦合。
- 支持多继承:Java 不支持类的多继承,但通过实现多个接口,一个类可以同时具有多个不同的行为。
2. 接口的语法规则
接口的定义:
interface InterfaceName {
// 抽象方法 (隐式地是 public abstract)
void methodName();
}
实现接口:
class ClassName implements InterfaceName {
@Override
public void methodName() {
// 接口方法的具体实现
}
}
示例:
interface Flyable {
void fly(); // 抽象方法
}
class Bird implements Flyable {
@Override
public void fly() {
System.out.println("鸟在飞");
}
}
解释:
Flyable
是一个接口,定义了一个抽象方法fly()
。Bird
类实现了Flyable
接口,并提供了fly()
方法的具体实现。
3. 接口的使用
接口不能直接使用,必须要有实现类来实现接口:
- 接口本身是不能实例化的,因为它没有具体的实现。要使用接口,必须有一个类实现该接口,提供接口中定义方法的具体实现。
接口的实现类必须实现接口中的所有抽象方法:
- 当一个类实现接口时,类必须实现接口中的所有方法。如果类没有实现所有方法,它必须声明为抽象类。
示例:
interface Drivable {
void drive();
}
class Car implements Drivable {
@Override
public void drive() {
System.out.println("汽车正在行驶");
}
}
public class Main {
public static void main(String[] args) {
Drivable myCar = new Car(); // 使用接口作为类型
myCar.drive(); // 输出:汽车正在行驶
}
}
解释:
Drivable
是一个接口,Car
实现了该接口,并提供了drive()
方法的实现。- 通过
Drivable
类型的引用,可以指向Car
对象,这也是多态性的一种表现。
4. 接口的特性
1. 接口是一种引用类型,但不能直接 new
接口的对象
- 接口本身是不能直接实例化的,因为它没有任何具体实现,必须通过实现类来创建对象。
// Flyable f = new Flyable(); // 错误!接口不能被实例化
Flyable bird = new Bird(); // 正确,通过实现类来实例化
2. 接口中的每个方法都是 public
和 abstract
的
interface Animal {
void eat(); // 等同于 public abstract void eat();
}
- 如果你尝试使用其他修饰符(如
protected
或private
),编译器将报错。
3. 接口中的方法不能有方法体,除非使用 default
方法
- 接口中的方法默认是抽象方法,不能有方法体。Java 8 之后,接口允许有
default
方法和static
方法,具体实现会在后面详细介绍。
interface Flyable {
void fly(); // 抽象方法,不能有实现
}
4. 重写接口中的方法时,不能使用默认的访问权限
- 实现接口方法时,访问权限必须是
public
。接口方法默认是public
,而 Java 中子类不能缩小方法的访问权限,因此实现接口的方法也必须是public
。
class Bird implements Flyable {
// 必须是public,不能使用默认或private
@Override
public void fly() {
System.out.println("鸟在飞");
}
}
5. 接口中的变量是 public static final
- 接口中的变量默认是常量,即
public static final
,必须在声明时初始化。它们是接口的全局常量,不能修改。
interface Flyable {
int MAX_HEIGHT = 1000; // 相当于 public static final int MAX_HEIGHT = 1000;
}
6. 接口中不能有静态代码块和构造方法
- 接口不属于类,因此不能有构造方法,也不能有静态代码块来初始化静态成员。
interface Flyable {
// static { System.out.println("不允许静态代码块"); } // 错误!
// Flyable() {} // 错误!接口不能有构造方法
}
7. 接口编译后也是 .class
文件
- 尽管接口不是类,但接口定义的字节码文件与类一样,都会生成
.class
文件,供 Java 虚拟机加载和使用。
8. 类没有实现接口中的所有抽象方法,必须声明为抽象类
- 如果类没有实现接口中的所有方法,那么这个类必须声明为抽象类。
abstract class Vehicle implements Drivable {
// 没有实现drive方法,因此必须是抽象类
}
9. Java 8 中的 default
方法和 static
方法
default
方法:Java 8 开始,接口可以包含default
方法。default
方法有具体实现,类可以选择性地重写它。这样,接口可以在不破坏现有实现类的情况下扩展新功能。
interface Flyable {
default void start() {
System.out.println("默认启动");
}
}
static
方法:接口也可以包含static
方法,可以通过接口名直接调用,不需要实现类的参与。
interface Flyable {
static void checkWeather() {
System.out.println("检查天气");
}
}
总结
- 接口的概念:接口定义了一组行为规范,没有具体实现,类通过实现接口来提供这些行为。
- 语法规则:接口使用
interface
关键字定义,方法默认是public abstract
,接口不能直接实例化,必须通过实现类来使用。 - 接口的使用:实现接口时,类必须实现接口的所有方法,未实现的方法会使类成为抽象类。
- 接口的特性:
- 接口中的方法默认是
public abstract
,变量是public static final
。 - 接口不能有构造方法和静态代码块。
- 从 Java 8 开始,接口可以包含
default
和static
方法。
- 接口中的方法默认是