在 Java 面向对象编程中,接口是实现规范定义、解耦代码和多态特性的核心技术。今天通过一个经典的「歌手大赛评分」实验,从零拆解接口的定义、实现、方法重写和多态调用,掌握接口在实际开发中的用法。

一、实验需求分析

歌手大赛评分规则:去掉一个最高分、去掉一个最低分,计算剩余分数的平均值作为最终得分;学校体重统计规则:直接计算所有体重数据的算术平均值。

需要用Java 接口实现:

  1. 定义一个统一的「平均值计算」规范接口;
  2. 两个实现类分别实现「歌手评分算法」和「体重平均算法」;
  3. 通过接口多态调用不同的计算逻辑,完成需求。

二、核心知识点前置

1. 什么是接口?

  • 接口是完全抽象的规范,只定义方法签名,不实现方法体;
  • interface 关键字定义,实现类必须重写接口中所有的抽象方法
  • 接口是实现多态的重要载体,支持「接口引用指向实现类对象」。

2. 方法重写(Override)

子类 / 实现类使用相同的方法名、参数列表、返回值类型,重新实现接口 / 父类的方法,是多态的基础。

3. 接口多态

接口类型 引用 = new 实现类对象();通过接口引用调用方法,会自动执行对应实现类的重写方法,灵活切换业务逻辑。

三、代码完整实现与解析

我们按照实验模板,补全代码并逐类讲解:

1. 定义平均值计算接口:ComputerAverage

接口定义统一的计算方法规范,所有实现类必须遵循:

// 平均值计算接口(规范定义)
public interface ComputerAverage {
    // 抽象方法:计算数组的平均值
    double average(double x[]);
}

注意:接口中方法默认 public abstract,无需手动修饰。

2. 歌手大赛实现类:SongGame

实现去掉最高最低分的评分逻辑,重写接口方法:

// 歌手大赛评分实现类
public class SongGame implements ComputerAverage {
    // 重写接口方法:实现歌手评分规则
    @Override
    public double average(double x[]) {
        int count = x.length;
        double aver = 0, temp;
        // 冒泡排序:从小到大排序分数
        for (int i = 0; i < count; i++) {
            for (int j = i; j < count; j++) {
                if (x[j] < x[i]) {
                    temp = x[j];
                    x[j] = x[i];
                    x[i] = temp;
                }
            }
        }
        // 跳过第一个(最低分)和最后一个(最高分),累加中间分数
        for (int i = 1; i < count - 1; i++) {
            aver += x[i];
        }
        // 避免数组长度小于3时除零错误
        if (count > 2) {
            aver = aver / (count - 2);
        } else {
            aver = 0;
        }
        return aver;
    }
}

3. 学校统计实现类:School

补全【代码 1】,实现算术平均值逻辑:

// 学校体重平均实现类
public class School implements ComputerAverage {
    // 【代码1】重写接口方法:计算算术平均值
    @Override
    public double average(double x[]) {
        double sum = 0;
        // 遍历数组累加所有元素
        for (double num : x) {
            sum += num;
        }
        // 算术平均 = 总和 / 元素个数
        return sum / x.length;
    }
}

4. 主测试类:Estimator

补全【代码 2】【代码 3】,通过接口多态调用方法:

// 主类:程序入口
public class Estimator {
    public static void main(String args[]) {
        // 歌手分数数组
        double a[] = {9.89,9.88,9.99,9.12,9.69,9.76,8.97};
        // 学生体重数组
        double b[] = {56,55.5,65,50,51.5,53.6,70,49,66,62,46};
        
        ComputerAverage computer; // 声明接口引用
        
        // 1. 接口引用指向歌手评分实现类
        computer = new SongGame();
        // 【代码2】调用歌手评分方法,传入分数数组
        double result = computer.average(a);
        System.out.printf("歌手最后得分:%5.3f\n", result);
        
        // 2. 接口引用指向体重平均实现类
        computer = new School();
        // 【代码3】调用体重平均方法,传入体重数组
        result = computer.average(b);
        System.out.printf("学生平均体重:%-5.2f kg", result);
    }
}

四、运行结果

歌手最后得分:9.780
学生平均体重:56.78 kg

五、核心知识点深度总结

1. 接口的核心作用

  • 统一规范:所有计算平均值的类,必须实现 average(double x[]) 方法;
  • 解耦代码:接口只定义规则,实现类负责具体逻辑,修改逻辑不影响接口调用。

2. 接口多态的优势

同一个接口引用 computer,可以动态切换SongGameSchool 对象,调用对应的重写方法,无需修改主类代码,极大提升代码扩展性。

3. 方法重写的要求

  • 方法名、参数列表、返回值类型必须和接口完全一致;
  • 实现类方法的访问权限必须大于等于接口方法(接口默认 public,实现类必须用 public)。

4. 实验中的细节处理

  • 歌手评分中对数组长度做判断(count>2),避免除零异常;
  • 冒泡排序实现分数排序,精准去掉最高、最低分;
  • 格式化输出(printf)保证结果展示美观。
Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐