← Java 学习路线(共 8 章)

第 4 章 类与对象

red wenzi · 2026-09-15 · 编程语言 · Java · 📖 预计阅读 13 分钟 · 共 2 道练习
🎯 本章你会学到:字段、构造器、this、封装,以及 static 与实例成员的区别。建议边读边敲,每节练习先自己做,再展开答案对照。

Java 里一切都是对象(除了基本类型),而且对象**一定在堆上**,由垃圾回收负责回收——所以你永远不会写 delete,也不会遇到悬垂指针。

定义并使用一个类

类、构造器与封装
public class Main {
    static class Student {
        private final String name;      // final:赋值后不能改
        private int score;

        Student(String name, int score) {   // 构造器:名字与类名相同,没有返回类型
            this.name = name;               // this 区分同名的字段与参数
            this.score = score;
        }

        String getName() { return name; }
        int getScore() { return score; }
        void addBonus(int delta) { this.score += delta; }

        @Override
        public String toString() { return name + ":" + score; }
    }

    public static void main(String[] args) {
        Student s = new Student("Ann", 90);
        s.addBonus(5);
        System.out.println(s);                      // 自动调用 toString()
        System.out.println(s.getName() + " " + s.getScore());
    }
}
运行结果
Ann:95
Ann 95

static:属于类,而不是属于对象

static 计数
public class Main {
    static class Counter {
        static int created = 0;          // 所有对象共用一份

        Counter() {
            created++;
        }
    }

    public static void main(String[] args) {
        new Counter();
        new Counter();
        new Counter();
        System.out.println("created=" + Counter.created);
        System.out.println("created=" + new Counter().created);  // 也能通过对象访问,但不推荐
    }
}
运行结果
created=3
created=4
⚠️ 易错点 字段有默认值(int 是 0、boolean 是 false、对象是 null),但**局部变量必须显式初始化**,否则编译不过——这一点比 C 安全。
⚠️ 易错点 用 == 比较两个对象是在比较引用(是不是同一个对象)。要比较内容,要么用 equals,要么自己写 equalshashCode

✍️ 本节练习

4.1必做矩形类

写一个 Rectangle 类(宽、高),提供 area()perimeter() 方法;读入两个数输出面积与周长(2 位小数)。

输入 一行两个实数:宽 高。

输出 两行:area=perimeter=(2 位小数)。

样例输入
3 4
样例输出
area=12.00
perimeter=14.00

💡 提示 构造器接收两个 double 存进字段;两个方法返回计算结果。

✅ 查看参考答案与解析
import java.util.Scanner;

public class Main {
    static class Rectangle {
        private final double width;
        private final double height;

        Rectangle(double width, double height) {
            this.width = width;
            this.height = height;
        }

        double area() { return width * height; }
        double perimeter() { return 2 * (width + height); }
    }

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        Rectangle r = new Rectangle(sc.nextDouble(), sc.nextDouble());
        System.out.printf("area=%.2f%n", r.area());
        System.out.printf("perimeter=%.2f%n", r.perimeter());
    }
}

解析 把数据(宽高)和行为(面积、周长)放在同一个类里,就是面向对象最基本的组织形式。

4.2挑战学生名单统计

定义 Student(姓名 + 分数),读入 n 个学生,输出平均分(2 位小数)和最高分学生的姓名。

输入 第一行 n;接下来 n 行「姓名 分数」。

输出 两行:avg=top=

样例输入
3
Ann 90
Bob 95
Cid 88
样例输出
avg=91.00
top=Bob

💡 提示 用对象数组存学生;一边读一边维护最高分(记住整个对象,最后取名字)。

✅ 查看参考答案与解析
import java.util.Scanner;

public class Main {
    static class Student {
        final String name;
        final int score;

        Student(String name, int score) {
            this.name = name;
            this.score = score;
        }
    }

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        Student[] list = new Student[n];
        long sum = 0;
        Student top = null;
        for (int i = 0; i < n; i++) {
            list[i] = new Student(sc.next(), sc.nextInt());
            sum += list[i].score;
            if (top == null || list[i].score > top.score) {
                top = list[i];
            }
        }
        System.out.printf("avg=%.2f%n", sum / (double) n);
        System.out.println("top=" + top.name);
    }
}

解析 Student[] list = new Student[n] 只是给引用开好位置,元素默认是 null,必须逐个 new

📚 本文概念都在知识大全:

JVM 与字节码 · JDK · String 与 StringBuilder · 集合框架 · 泛型 · 受检异常 · 继承与接口 · record · Stream API