杰瑞科技汇

Java interface定义的关键语法和核心特性是什么?

什么是接口?

在 Java 中,接口(Interface) 是一种引用数据类型,它和 class(类)处于同一层次,你可以把它理解为一份 “契约”“规范”

Java interface定义的关键语法和核心特性是什么?-图1
(图片来源网络,侵删)

这份契约定义了一组方法(方法签名),但没有提供具体实现,任何类 implements(实现)了这个接口,就必须遵守契约,提供所有这些方法的具体实现。

核心思想:

  • 定义“能做什么” (What):接口只声明方法,不关心“怎么做”(How)。
  • 实现“具体怎么做”:具体的类来实现接口,提供方法体。

这完美地体现了面向对象编程中的 “面向接口编程” 思想,它极大地提高了代码的灵活性、可扩展性和解耦性。


接口的语法定义

1 基本语法

// [public] interface 接口名 [extends 父接口1, 父接口2, ...] {
//     // 零个或多个常量定义
//     // 零个或多个抽象方法定义
// }

2 一个简单的例子

我们先来看一个最基础的接口定义。

Java interface定义的关键语法和核心特性是什么?-图2
(图片来源网络,侵删)

Flyable.java - 定义一个“飞行”的能力接口

/**
 * 定义一个飞行能力的接口
 * 这是一个规范,任何能飞的物体都必须实现这个接口。
 */
public interface Flyable {
    // 1. 接口中可以定义常量
    // 注意:常量默认是 public static final 的,所以可以省略修饰符
    double MAX_SPEED = 1000.0; // 最大速度
    double MIN_SPEED = 0.0;   // 最小速度
    // 2. 接口中可以定义抽象方法
    // 注意:抽象方法默认是 public abstract 的,所以可以省略修饰符
    void fly(); // 飞行的方法
    // 在 Java 8 之前,接口中只能有抽象方法和常量
}

接口的核心特性

在 Java 8 之前,接口的特性非常严格,但从 Java 8 开始,接口的能力得到了极大的增强。

1 Java 8 之前的特性

  1. public static final 常量

    • 接口中定义的变量,默认被 public, static, final 修饰。
    • 这意味着它们是 公共的静态的(属于接口本身,而不是实例)、最终的(常量,不可修改)。
    • 通常我们直接写 int AGE = 18;,编译器会自动加上这三个修饰符。
  2. public abstract 抽象方法

    Java interface定义的关键语法和核心特性是什么?-图3
    (图片来源网络,侵删)
    • 接口中定义的方法,默认被 public, abstract 修饰。
    • 这意味着它们是 公共的抽象的(没有方法体,由实现类提供具体逻辑)。
    • 通常我们直接写 void doSomething();
  3. 不能有构造方法

    接口不能被实例化,因此它没有构造方法。

  4. 一个类可以实现多个接口

    • 这是 Java 实现多重继承能力的方式,一个类可以同时遵守多个“契约”。
    • 语法:class ClassName implements InterfaceA, InterfaceB, ...

2 Java 8 引入的新特性(重要更新)

为了支持 函数式编程Lambda 表达式,Java 8 为接口引入了新的成员。

  1. 默认方法

    • 使用 default 关键字修饰,可以拥有方法体。
    • 作用:允许接口提供方法的默认实现,这样,实现类可以不必重写这个方法,直接使用接口提供的默认实现。
    • 解决了接口演化问题:可以在不破坏现有实现类代码的情况下,向接口中添加新方法。
    public interface Flyable {
        void fly();
        // 默认方法
        default void takeOff() {
            System.out.println("准备起飞...");
        }
    }
  2. 静态方法

    • 使用 static 关键字修饰,可以拥有方法体。
    • 作用:提供与接口相关的工具性方法,它们属于接口本身,不能被实现类继承或重写。
    • 调用方式:InterfaceName.staticMethodName();
    public interface Flyable {
        // 静态方法
        static void logFlightInfo() {
            System.out.println("记录飞行日志...");
        }
    }

3 Java 9 引入的新特性

  1. 私有方法

    • 使用 private 关键字修饰,可以拥有方法体。
    • 作用:提高代码复用性,当一个接口中有多个默认方法或静态方法,并且它们包含一些共同的逻辑代码时,可以将这些公共代码提取到私有方法中,供其他接口方法调用。
    • 私有方法分为两类:
      • private:供接口中的默认方法和私有方法调用。
      • private static:供接口中的静态方法和私有静态方法调用。
    public interface Flyable {
        default void flyAndLand() {
            System.out.println("开始飞行...");
            commonFlightLogic(); // 调用私有方法
            System.out.println("安全降落。");
        }
        // 私有方法
        private void commonFlightLogic() {
            System.out.println("执行通用的飞行逻辑...");
        }
    }

接口的实现

一个类使用 implements 关键字来实现一个或多个接口。

Bird.java - 实现飞行接口

// Bird 类实现了 Flyable 接口
public class Bird implements Flyable {
    @Override
    public void fly() {
        System.out.println("小鸟用翅膀飞翔,速度很快。");
    }
    // Bird 类可以选择不重写 takeOff() 方法,直接使用 Flyable 接口提供的默认实现
}

Airplane.java - 实现飞行接口

// Airplane 类也实现了 Flyable 接口
public class Airplane implements Flyable {
    @Override
    public void fly() {
        System.out.println("飞机通过引擎和机翼高速飞行。");
    }
    // Airplane 类也可以选择重写默认方法,提供自己的实现
    @Override
    public void takeOff() {
        System.out.println("飞机在跑道上加速,然后起飞。");
    }
}

Test.java - 测试

public class Test {
    public static void main(String[] args) {
        Flyable bird = new Bird();
        bird.fly();      // 输出: 小鸟用翅膀飞翔,速度很快。
        bird.takeOff();  // 输出: 准备起飞... (使用默认实现)
        Flyable airplane = new Airplane();
        airplane.fly();  // 输出: 飞机通过引擎和机翼高速飞行。
        airplane.takeOff(); // 输出: 飞机在跑道上加速,然后起飞。 (重写后的实现)
        // 调用接口的静态方法
        Flyable.logFlightInfo(); // 输出: 记录飞行日志...
    }
}

接口与抽象类的区别

这是一个非常经典和重要的问题,它们既有相似之处,又有本质区别。

特性 接口 抽象类
继承/实现 implements,一个类可以实现多个接口 extends,一个类只能继承一个抽象类(单继承)
构造方法 没有构造方法 构造方法,子类在创建时会先调用父类的构造方法
方法 - Java 8 之前:只有抽象方法
- Java 8+:默认方法、静态方法、私有方法
可以包含抽象方法和具体方法(有方法体的普通方法)
成员变量 只能是 public static final 常量 可以是各种类型的变量(普通成员变量、静态变量等)
设计目的 规范,定义一种能力或行为,强调“是什么”(What),如 Runnable, Serializable 模板,定义一个事物的基础结构,强调“是什么”以及“部分怎么做”(How),如 Animal
访问修饰符 方法和常量默认是 public 方法和变量可以是 public, protected, private

简单总结:

  • 当你需要定义一种能力或行为规范,并且希望任何类都能自由地实现这种能力时,使用接口。
  • 当你定义一个“事物”的基类,这个基类有一些共同的状态(成员变量)和部分共同的行为(方法实现),并且希望子类继承和扩展时,使用抽象类。

Java 接口是一个强大且灵活的特性,它的定义和功能随着 Java 版本的更新而不断演进:

  • Java 7 及以前:纯粹的“契约”,包含常量和抽象方法。
  • Java 8:引入了 默认方法静态方法,增强了接口的功能,使其更易于扩展和提供工具方法。
  • Java 9:引入了 私有方法,提高了接口内部代码的复用性。

理解接口的定义和特性是掌握 Java 面向对象编程和现代 Java 开发(如 Spring 框架)的关键,它为实现 解耦多态面向接口编程 提供了坚实的基础。

分享:
扫描分享到社交APP
上一篇
下一篇