Android/Java 中接口(Interface)的使用场景、用途和方法

发布于:2025-09-06 ⋅ 阅读:(16) ⋅ 点赞:(0)

一、接口(Interface)的用途和核心思想

接口的核心思想是:定义一套行为规范或契约。它只规定“应该做什么”(方法声明),但不关心“具体怎么做”(方法实现)。

其主要用途可以概括为:

  1. 实现多态(Polymorphism): 这是接口最重要的用途。一个类可以实现多个接口,从而可以被当做不同的类型来使用,极大地增加了代码的灵活性。
  2. 实现完全抽象: 在 Java 8 之前,接口是所有方法都是抽象且未实现的纯粹抽象类。它强制实现类提供所有方法的具体实现,确保了规范的执行。
  3. 降低耦合(Decoupling): 代码依赖于接口(抽象),而不是具体的实现类。这使得你可以轻松替换不同的实现,而不影响其他部分的代码。这是软件设计原则(如依赖倒置原则)的核心。
  4. 定义回调机制(Callback): 正如监听器(Listener)所示,接口是实现回调的完美工具。你提供一个接口,别人(系统或其他类)会在特定时机调用你实现的方法。

二、关键特性和语法演变(Java 7 → Java 8+)

接口的特性随着 Java 版本在不断演进,这在 Android 开发中(取决于你设置的 compileSdkVersiontargetSdkVersion)同样适用。

Java 7 及以前(传统接口)
  • 抽象方法(Abstract Methods): 接口中的方法默认是 public abstract 的,不能有方法体。实现类必须重写所有这些方法。

    public interface Animal {
        void eat();   // 默认就是 public abstract void eat();
        void sleep(); // 默认就是 public abstract void sleep();
    }
    
  • 常量(Constants): 接口中定义的变量默认是 public static final 的(即常量)。

    public interface Constants {
        int MAX_SPEED = 100; // 默认就是 public static final int MAX_SPEED = 100;
    }
    
Java 8 及以后(现代接口)

为了增强接口的灵活性,Java 8 引入了两个重要的新特性:

  • 默认方法(Default Methods): 使用 default 关键字修饰的方法。它可以有方法体。

    • 用途: 当需要为接口添加新方法时,为了避免破坏所有已有的实现类,可以提供一個默认实现。这样已有的实现类无需做任何修改。
    public interface Vehicle {
        void start(); // 传统抽象方法
    
        // Java 8 默认方法
        default void honk() {
            System.out.println("Beep beep!");
        }
    }
    // 实现类可以选择不重写 honk(),直接使用默认实现
    public class Car implements Vehicle {
        @Override
        public void start() {
            System.out.println("Car starts with key.");
        }
        // 没有重写 honk(),使用 Vehicle 接口的默认实现
    }
    
  • 静态方法(Static Methods): 使用 static 关键字修饰的方法。它属于接口本身,而不是实现类的实例。通过接口名直接调用。

    • 用途: 提供与接口相关的工具方法,这些方法不需要依赖对象实例。
    public interface MathOperations {
        static int add(int a, int b) {
            return a + b;
        }
    }
    // 调用方式:MathOperations.add(5, 3); // 输出 8
    

三、主要使用场景

1. 定义回调机制 / 监听器模式 (Most Common in Android)

这是 Android 开发中最常见的接口用法。

// 1. 定义回调接口
public interface OnDownloadCompleteListener {
    void onComplete(String filePath);
    void onError(Exception e);
}

// 2. 在一个服务类中持有接口引用并提供设置方法
public class DownloadManager {
    private OnDownloadCompleteListener mListener;

    public void setOnDownloadCompleteListener(OnDownloadCompleteListener listener) {
        this.mListener = listener;
    }

    public void startDownload(String url) {
        // 模拟下载过程...
        new Thread(() -> {
            try {
                // ... 下载逻辑
                // 3. 在完成后回调
                if (mListener != null) {
                    mListener.onComplete("/sdcard/downloaded_file.zip");
                }
            } catch (Exception e) {
                if (mListener != null) {
                    mListener.onError(e);
                }
            }
        }).start();
    }
}

// 4. 在Activity中实现接口并设置监听器
public class MainActivity extends AppCompatActivity implements OnDownloadCompleteListener {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        DownloadManager manager = new DownloadManager();
        manager.setOnDownloadCompleteListener(this); // 设置监听器
        manager.startDownload("http://example.com/file.zip");
    }

    // 5. 实现回调方法
    @Override
    public void onComplete(String filePath) {
        runOnUiThread(() -> Toast.makeText(this, "Downloaded: " + filePath, Toast.LENGTH_SHORT).show());
    }

    @Override
    public void onError(Exception e) {
        runOnUiThread(() -> Toast.makeText(this, "Error: " + e.getMessage(), Toast.LENGTH_SHORT).show());
    }
}
2. 实现多态和策略模式

根据不同情况使用不同的算法或策略。

// 定义策略接口
public interface PaymentStrategy {
    void pay(double amount);
}

// 实现不同的策略
public class CreditCardPayment implements PaymentStrategy {
    @Override
    public void pay(double amount) {
        System.out.println("Paid " + amount + " using Credit Card.");
    }
}

public class PayPalPayment implements PaymentStrategy {
    @Override
    public void pay(double amount) {
        System.out.println("Paid " + amount + " using PayPal.");
    }
}

// 使用策略的上下文类
public class ShoppingCart {
    private PaymentStrategy paymentStrategy;

    public void setPaymentStrategy(PaymentStrategy strategy) {
        this.paymentStrategy = strategy;
    }

    public void checkout(double amount) {
        paymentStrategy.pay(amount);
    }
}

// 使用
ShoppingCart cart = new ShoppingCart();
cart.setPaymentStrategy(new CreditCardPayment()); // 可以轻松替换策略
cart.checkout(100.0);
3. 依赖抽象,而非具体实现(降低耦合)

这是优秀架构设计的关键。

// 接口(抽象)
public interface UserRepository {
    User getUserById(int id);
    void saveUser(User user);
}

// 具体实现1:数据库存储
public class DatabaseUserRepository implements UserRepository {
    @Override
    public User getUserById(int id) { /* SQLite 查询逻辑 */ }
    @Override
    public void saveUser(User user) { /* SQLite 插入逻辑 */ }
}

// 具体实现2:网络API存储
public class ApiUserRepository implements UserRepository {
    @Override
    public User getUserById(int id) { /* 网络请求逻辑 */ }
    @Override
    public void saveUser(User user) { /* 网络请求逻辑 */ }
}

// 业务逻辑类,它只依赖接口,不关心具体实现
public class UserManager {
    private final UserRepository repository; // 依赖接口

    // 通过构造函数注入依赖(Dependency Injection)
    public UserManager(UserRepository repo) {
        this.repository = repo;
    }

    public void updateUserProfile(User user) {
        // 业务逻辑...
        repository.saveUser(user); // 调用接口方法,不关心是存到数据库还是网络
    }
}
// 这样,测试时你可以传入一个 Mock 实现,非常方便。

四、接口 vs. 抽象类

这是一个经典面试题。它们很相似,但有关键区别:

特性 接口 (Interface) 抽象类 (Abstract Class)
方法实现 Java 8 前不能有,之后可以有默认/静态方法 可以有抽象方法,也可以有具体实现的方法
成员变量 只能是常量 (public static final) 可以是普通变量、常量、静态变量
构造方法 没有构造方法 构造方法(虽然不能实例化,但子类可以调用)
继承 一个类可以实现多个接口 一个类只能继承一个抽象类
设计目的 “has-a” 关系,定义行为契约、能力 “is-a” 关系,定义是什么,提供模板
访问修饰符 方法默认 public 方法可以有 public, protected, private

如何选择?

  • 如果你主要关心的是定义一组行为能力,并且不相关的类可能需要共享这些行为,使用接口。(例如:Comparable(可比较), Serializable(可序列化))。
  • 如果你要定义一些紧密相关的对象的基本模板,并且其中包含一些公共的实现代码,使用抽象类。(例如:Animal 作为 Dog, Cat 的基类)。

总结

接口是 Java/Android 实现抽象多态低耦合代码的最强大工具之一。

  1. 用途: 定义契约、实现多态、解耦代码、实现回调。
  2. 核心方法抽象方法(必须实现)、默认方法(可选实现)、静态方法(接口工具方法)。
  3. 主要场景
    • Android 监听器/回调 (最常见)
    • 策略模式等设计模式
    • 依赖注入和架构设计(如 Repository 模式)
  4. 关键优势一个类可以实现多个接口,提供了比继承更灵活的代码复用方式。

网站公告

今日签到

点亮在社区的每一天
去签到