学习Java42天

接口 (Interface)

一、接口的基本概念

1. 定义与性质
  • 定义 :接口是 Java 中的一种引用数据类型 ,用于定义一组行为规范规则

  • 关键字interface

  • 格式

    java

    复制代码
    public interface 接口名 {
        // 接口内容
    }
  • 核心性质

    • 接口不能被实例化 (不能 new 接口)。

    • 接口主要用来定义类必须遵循的规则(方法声明)。

    • 它是一种纯粹的 "是什么能做什么" 的契约。

2. 实现关系
  • 关键字implements

  • 格式

    java

    复制代码
    public class 类名 implements 接口名 {
        // 类的内容
    }

    实现了接口的类称为该接口的 "实现类"

3. 实现类的规则

当一个普通类实现一个接口时:

  1. 必须重写接口中的所有抽象方法(推荐,成为具体类)

  2. 或者将自己声明为抽象类(如果不重写所有抽象方法)

java

复制代码
// 定义接口
public interface Animal {
    void eat(); // 抽象方法(默认 public abstract)
    void sleep();
}

// 实现方式1:重写所有方法
public class Dog implements Animal {
    @Override
    public void eat() {
        System.out.println("狗吃骨头");
    }
    
    @Override
    public void sleep() {
        System.out.println("狗在睡觉");
    }
}

// 实现方式2:成为抽象类
public abstract class Cat implements Animal {
    @Override
    public void eat() {
        System.out.println("猫吃鱼");
    }
    // 没有重写 sleep() 方法,所以 Cat 必须是抽象类
}

二、接口与类的关系

1. 实现关系的特点
  • 单实现:一个类实现一个接口

  • 多实现 :一个类可以实现多个接口

  • 继承与实现共存:一个类可以继承一个父类的同时实现多个接口

java

复制代码
// 多实现示例
public interface Swimmable {
    void swim();
}

public interface Flyable {
    void fly();
}

// 一个类实现多个接口
public class Duck implements Swimmable, Flyable {
    @Override
    public void swim() {
        System.out.println("鸭子在游泳");
    }
    
    @Override
    public void fly() {
        System.out.println("鸭子在飞");
    }
}

// 继承与实现共存
public class Animal {
    public void breathe() {
        System.out.println("呼吸");
    }
}

public class SuperDuck extends Animal implements Swimmable, Flyable {
    @Override
    public void swim() {
        System.out.println("超级鸭游泳");
    }
    
    @Override
    public void fly() {
        System.out.println("超级鸭飞翔");
    }
}
2. 类、接口之间的各种关系总结
关系类型 关键字 特点
类与类 extends 单继承,不支持多继承,但支持多层继承
类与接口 implements 多实现,一个类可以实现多个接口
接口与接口 extends 多继承,一个接口可以继承多个接口

接口多继承示例

java

复制代码
public interface A {
    void methodA();
}

public interface B {
    void methodB();
}

// 接口C继承接口A和B
public interface C extends A, B {
    void methodC();
}

// 实现类需要实现所有抽象方法
public class MyClass implements C {
    @Override
    public void methodA() { /* 实现 */ }
    
    @Override
    public void methodB() { /* 实现 */ }
    
    @Override
    public void methodC() { /* 实现 */ }
}

三、接口的成员特点(JDK 7 及以前)

在 JDK 8 之前,接口中只能包含以下内容:

成员类型 特点 默认修饰符 示例
成员变量 常量,必须初始化 public static final int MAX_VALUE = 100;
构造方法 没有 - -
成员方法 抽象方法 public abstract void doSomething();

示例

java

复制代码
public interface MyInterface {
    // 常量(public static final 可以省略)
    public static final int MAX = 100;
    String NAME = "接口"; // 等价于 public static final String NAME = "接口";
    
    // 抽象方法(public abstract 可以省略)
    public abstract void show();
    void doWork(); // 等价于 public abstract void doWork();
    
    // 不能有构造方法
    // public MyInterface() {} // 编译错误!
    
    // 不能有普通方法
    // public void normalMethod() { } // 编译错误!
}

四、JDK 8 及以后接口的新特性

1. 默认方法(Default Method)
  • 目的 :解决接口升级问题。当接口需要添加新方法时,如果直接添加抽象方法,会导致所有实现类都要修改。默认方法提供了默认实现,不会破坏现有代码。

  • 格式

    java

    复制代码
    public default 返回值类型 方法名(参数列表) {
        // 方法体
    }
  • 特点

    • 使用 default 关键字修饰

    • 不是抽象方法,所以不强制重写

    • public 可以省略,但 default 不能省略

    • 可以被实现类直接继承使用,也可以被重写

java

复制代码
public interface USB {
    // 抽象方法
    void connect();
    
    // 默认方法(解决接口升级问题)
    default void transferData() {
        System.out.println("默认的数据传输方式");
    }
    
    // JDK 8 也可以有静态方法
    static void showVersion() {
        System.out.println("USB 3.0");
    }
}

public class Mouse implements USB {
    @Override
    public void connect() {
        System.out.println("鼠标已连接");
    }
    
    // 可以不重写 transferData(),使用默认实现
}

public class Keyboard implements USB {
    @Override
    public void connect() {
        System.out.println("键盘已连接");
    }
    
    // 也可以重写默认方法
    @Override
    public void transferData() {
        System.out.println("键盘使用特殊方式传输数据");
    }
}
2. 默认方法的冲突规则

当实现类实现了多个接口,且这些接口有同名的默认方法时:

java

复制代码
public interface A {
    default void show() {
        System.out.println("A的show方法");
    }
}

public interface B {
    default void show() {
        System.out.println("B的show方法");
    }
}

// 编译错误:必须重写show方法解决冲突
public class C implements A, B {
    @Override
    public void show() {
        // 可以选择调用某一个接口的默认方法
        A.super.show(); // 调用A接口的show方法
        // 或者提供自己的实现
        System.out.println("C重写的show方法");
    }
}
3. 静态方法(JDK 8)
  • 格式public static 返回值类型 方法名(参数列表) { }

  • 特点

    • 属于接口本身,通过 接口名.方法名() 调用

    • 不能被子类继承或重写

    • 常用于工具方法

java

复制代码
public interface MathUtils {
    static int max(int a, int b) {
        return a > b ? a : b;
    }
}

// 使用
int result = MathUtils.max(10, 20);
4. 私有方法(JDK 9)
  • 目的 :为默认方法或静态方法提供内部辅助方法,抽取公共代码,提高代码复用性。

  • 格式

    java

    复制代码
    // 普通私有方法:为默认方法服务
    private 返回值类型 方法名(参数列表) { }
    
    // 静态私有方法:为静态方法服务
    private static 返回值类型 方法名(参数列表) { }
  • 特点:只能在接口内部使用

java

复制代码
public interface DataProcessor {
    default void processData(String data) {
        String cleaned = cleanData(data); // 调用私有方法
        System.out.println("处理数据: " + cleaned);
    }
    
    static void validate(String data) {
        if (isValid(data)) { // 调用私有静态方法
            System.out.println("数据有效");
        }
    }
    
    // 私有方法(JDK 9+)
    private String cleanData(String data) {
        return data.trim().toLowerCase();
    }
    
    // 私有静态方法(JDK 9+)
    private static boolean isValid(String data) {
        return data != null && !data.isEmpty();
    }
}

五、接口总结对比

版本 成员变量 构造方法 成员方法
JDK 7 及以前 只能是常量 public static final 没有 只能是抽象方法 public abstract
JDK 8 同上 同上 抽象方法、默认方法(default)、静态方法(static)
JDK 9 同上 同上 增加了私有方法(private)、私有静态方法

六、适配器设计模式

1. 问题场景

当一个接口中有大量抽象方法,但实现类只需要使用其中一部分时,如果直接实现接口,就需要重写所有方法(即使大部分方法体为空)。这会导致代码冗余。

2. 解决方案:适配器模式
  • 核心思想 :创建一个中间适配器类 ,对接口中的所有方法进行空实现

  • 实现步骤

    1. 定义中间类 XXXAdapter,用 abstract 修饰,防止被实例化。

    2. 空实现接口中的所有抽象方法(方法体为空 {})。

    3. 真正的实现类继承适配器类,只重写需要的方法。

3. 完整示例

java

复制代码
// 1. 定义接口(有很多方法)
public interface WindowListener {
    void windowOpened();
    void windowClosing();
    void windowClosed();
    void windowIconified();
    void windowDeiconified();
    void windowActivated();
    void windowDeactivated();
}

// 2. 创建适配器类(中间类)
public abstract class WindowAdapter implements WindowListener {
    // 空实现所有方法
    @Override
    public void windowOpened() {}
    
    @Override
    public void windowClosing() {}
    
    @Override
    public void windowClosed() {}
    
    @Override
    public void windowIconified() {}
    
    @Override
    public void windowDeiconified() {}
    
    @Override
    public void windowActivated() {}
    
    @Override
    public void windowDeactivated() {}
}

// 3. 真正的实现类
public class MyWindow extends WindowAdapter {
    // 只需要重写关心的方法
    @Override
    public void windowClosing() {
        System.out.println("窗口正在关闭,执行清理操作...");
        System.exit(0);
    }
    
    @Override
    public void windowOpened() {
        System.out.println("窗口已打开");
    }
    
    // 其他方法使用适配器中的空实现,无需重写
}

// 4. 使用
public class Test {
    public static void main(String[] args) {
        MyWindow window = new MyWindow();
        // 只会执行重写的方法
        window.windowOpened();    // 输出:窗口已打开
        window.windowClosing();   // 输出:窗口正在关闭,执行清理操作...
        window.windowClosed();    // 无输出(使用空实现)
    }
}

七、接口的应用场景

  1. 定义标准/规范:如 JDBC 接口、Servlet 接口

  2. 解耦:面向接口编程,降低模块间耦合度

  3. 扩展性:通过实现不同接口,为类添加不同能力

  4. 替代多继承:Java 不支持类的多继承,但支持接口的多实现

设计原则面向接口编程,而不是面向实现编程。这样可以提高代码的灵活性、可扩展性和可维护性。

相关推荐
AI视觉网奇2 小时前
ue5 开发 web socket server 实战2026
c++·学习·ue5
嗯嗯=2 小时前
STM32单片机学习篇6
stm32·单片机·学习
2501_944526422 小时前
Flutter for OpenHarmony 万能游戏库App实战 - 知识问答游戏实现
android·开发语言·javascript·python·flutter·游戏·harmonyos
找了一圈尾巴2 小时前
智能体自演进框架-ACE(论文学习)
学习·提示词
chilavert3182 小时前
技术演进中的开发沉思-325 JVM:java体系技术全貌(下)
java·开发语言·jvm
chilavert3182 小时前
技术演进中的开发沉思-324 JVM:java技术体系全貌(上)
java·开发语言
pcm1235672 小时前
通信服务前沿知识
java
ValidationExpression2 小时前
学习:企业标准的容器化 CI,CD 发布流程
学习·ci/cd
式5162 小时前
大模型学习基础(九)LoRA微调原理
人工智能·深度学习·学习