
简介这份资源是东北大学Java面向对象实验1至6的完整代码合集面向正在学习Java OOP课程的高校学生及自学者帮助解决实验无从下手、缺少参考实现的问题。压缩包共124个文件约51KB以java源码与class字节码为主辅以html说明页、dat数据文件、xml配置及少量gif、jar等覆盖从类与对象、封装、继承、多态到接口、异常处理、集合框架、文件流等核心知识点内容预览中可见GourmetCoffeeGUI、CatalogGUI、FileCatalogLoader等图形界面与目录加载相关类说明实验涉及GUI编程与数据持久化。目前已有2002人学习下载热度较高。读者可据此对照六个实验的完整实现理解构造器初始化、方法重写、接口实现与集合存储等具体写法并参考目录结构与类间关系梳理设计思路适合作为课程实验的对照参考与查漏补缺之用。1. Java 面向对象实验全貌从类与对象到异常处理的六次递进很多人学 Java 面向对象课上听懂了封装继承多态一打开实验代码就不知道从哪下手。这套实验代码 1 到 6 的价值恰恰在于它把「面向对象到底怎么落地」拆成了六个可运行的递进模块。梳理下来会发现它的主线非常清晰前两个实验打地基聚焦类、对象、构造方法、封装中间两个实验进入继承、多态、抽象类与接口这是整个方向最核心也最容易翻车的部分最后两个实验处理异常、集合与文件读写把语法能力拉进真实场景。它适合正在系统学 Java 的人对照复习也适合考前想快速查漏补缺的人按模块过一遍。整份代码不是孤立的习题而是一条从「定义单个类」到「多个类协作完成数据持久化」的完整链路每一环都在为下一环铺路。2. 类与对象地基实验 1 到 2 的封装与构造复习重点2.1 实验 1 到底在练什么类、属性、方法三件套实验 1 通常从最简单的类定义开始比如定义一个学生类或矩形类包含若干私有属性和公开方法。这个阶段的核心不是写出多复杂的逻辑而是建立「属性私有、方法公开」的肌肉记忆。梳理下来会发现实验 1 最容易忽略的是构造方法的重载——很多同学只写一个无参构造结果后面需要初始化对象时只能一个个 set代码又臭又长。以矩形类为例标准写法应该同时提供无参构造和带参构造public class Rectangle { private double width; private double height; // 无参构造给默认值 public Rectangle() { this.width 1.0; this.height 1.0; } // 带参构造初始化时直接赋值 public Rectangle(double width, double height) { this.width width; this.height height; } public double getArea() { return width * height; } public double getPerimeter() { return 2 * (width height); } }这里this.width width中的this不能省否则就是自己赋值给自己属性永远是 0。参数说明上width和height用double而不是int是为了后面计算面积时保留小数精度。实验 1 的复习重点就三条属性用private、方法用public、构造方法至少写两个。2.2 实验 2 的封装进阶getter/setter 与 toString 的规范写法实验 2 一般会要求对实验 1 的类做封装强化加上完整的 getter 和 setter并且重写toString方法。这个实验看起来简单但它是后面所有实验的模板。梳理下来会发现getter/setter 不是机械生成就完事有几个细节直接决定后面会不会踩坑。第一setter 里要不要做参数校验比如年龄不能为负数实验 2 通常不强制但如果你在这里加上校验后面实验 5 的异常处理会轻松很多。第二toString的返回值格式要统一建议用类名[属性1值, 属性2值]这种形式方便调试时直接打印对象看状态。第三布尔类型的 getter 习惯上用isXxx而不是getXxx这是 JavaBean 规范里明确写的考试和代码审查都会看。public class Student { private String name; private int age; public String getName() { return name; } public void setName(String name) { this.name name; } public int getAge() { return age; } public void setAge(int age) { if (age 0) { throw new IllegalArgumentException(年龄不能为负); } this.age age; } Override public String toString() { return Student[name name , age age ]; } }这段代码里Override注解建议每次都写它能在编译期帮你检查方法签名是否写错。实验 2 的易错点集中在toString拼字符串时漏掉逗号或引号导致输出格式混乱复习时对着控制台输出逐字检查一遍就能避免。3. 继承与多态主线实验 3 到 4 的抽象类与接口对比3.1 实验 3 的继承体系extends、super 与方法重写实验 3 开始引入继承典型场景是定义一个父类如形状类再派生出圆、矩形等子类。这个实验的复习重点是extends关键字、super调用父类构造方法、以及方法重写的规则。梳理下来会发现继承里最容易翻车的地方是构造方法的调用链——子类构造方法第一行如果没有显式写super(...)编译器会自动插入super()但父类如果只定义了带参构造就会直接编译报错。public class Shape { protected String name; public Shape(String name) { this.name name; } public double getArea() { return 0.0; } } public class Circle extends Shape { private double radius; public Circle(double radius) { super(圆形); // 必须显式调用因为父类没有无参构造 this.radius radius; } Override public double getArea() { return Math.PI * radius * radius; } }参数说明protected修饰的name允许子类直接访问但更推荐用private加 getter。方法重写要求方法名、参数列表、返回类型完全一致访问权限不能比父类更严格。实验 3 的复习重点就是一句话子类构造先调父类重写方法签名要一致。3.2 实验 4 的多态落地抽象类与接口怎么选实验 4 通常要求把实验 3 的父类改造成抽象类或者抽出一个接口然后通过父类引用指向子类对象来体现多态。这是整个方向的分水岭也是考试里最爱出对比题的地方。梳理下来会发现抽象类和接口的选择有一个很实用的判断标准如果多个类共享的是「是什么」的关系用抽象类如果共享的是「能做什么」的能力用接口。对比维度抽象类接口关键字abstract classinterface方法实现可以有具体方法默认方法外均为抽象构造方法有无多继承不支持支持多实现适用场景共享属性和基础实现定义统一行为契约public interface Drawable { void draw(); // 默认 public abstract } public abstract class Shape implements Drawable { protected String name; public Shape(String name) { this.name name; } public abstract double getArea(); } public class Circle extends Shape { private double radius; public Circle(double radius) { super(圆形); this.radius radius; } Override public double getArea() { return Math.PI * radius * radius; } Override public void draw() { System.out.println(绘制 name 面积 getArea()); } }多态的调用规则是编译看左边运行看右边。Shape s new Circle(5);这行代码编译时检查Shape类有没有getArea方法运行时执行Circle的重写版本。实验 4 的易错点是把接口当成抽象类用在接口里写实例变量——接口里的变量默认是public static final写int x 1;其实是个常量不能改。4. 异常、集合与文件实验 5 到 6 的工程化收尾4.1 实验 5 的异常处理try-catch-finally 与自定义异常实验 5 一般会要求给前面的类加上异常处理比如输入非法参数时抛出异常或者读取数据时捕获NumberFormatException。这个实验的复习重点是异常的分类、try-catch-finally的执行顺序、以及自定义异常的写法。梳理下来会发现最容易忽略的是finally块里不要写return否则会覆盖try里的返回值这是个经典翻车点。public class AgeValidator { public static void validate(int age) throws InvalidAgeException { if (age 0 || age 150) { throw new InvalidAgeException(年龄不合法: age); } } public static void main(String[] args) { try { validate(-5); } catch (InvalidAgeException e) { System.err.println(捕获异常: e.getMessage()); } finally { System.out.println(校验结束); } } } class InvalidAgeException extends Exception { public InvalidAgeException(String message) { super(message); } }参数说明自定义异常继承Exception表示受检异常调用方必须处理继承RuntimeException表示非受检异常可以不强制捕获。实验 5 的复习重点是对比受检和非受检的使用场景——业务校验用受检编程错误用非受检。4.2 实验 6 的集合与文件ArrayList 与 IO 流的配合实验 6 通常是综合实验要求把对象存进集合再写入文件或从文件读取。这个实验把前面所有知识点串起来定义类、封装、继承、多态、异常处理最后用集合和 IO 落地。梳理下来会发现最容易出错的地方是文件读写时的资源关闭和字符编码。public class StudentManager { private ListStudent students new ArrayList(); public void addStudent(Student s) { students.add(s); } public void saveToFile(String path) { try (BufferedWriter writer new BufferedWriter( new OutputStreamWriter(new FileOutputStream(path), UTF-8))) { for (Student s : students) { writer.write(s.toString()); writer.newLine(); } } catch (IOException e) { System.err.println(写入失败: e.getMessage()); } } }这里用了 try-with-resources 语法BufferedWriter会在 try 块结束后自动关闭不需要手动写finally里的close。参数说明OutputStreamWriter的第二个参数指定编码为 UTF-8避免中文乱码。实验 6 的复习重点是集合的增删改查 API 和 IO 流的装饰器模式——FileOutputStream套OutputStreamWriter再套BufferedWriter一层层增强功能。5. 易漏点与易错点六次实验里最容易翻车的五个地方5.1 构造方法链断裂子类忘了调 super易漏点子类构造方法里没有显式写super(...)而父类又没有无参构造。为什么漏编译器自动插入super()的规则只在父类有无参构造时成立一旦父类只定义了带参构造编译直接报错但报错信息指向子类构造方法很多人第一反应是去改子类其实根在父类。怎么补写子类构造方法时第一行永远先写super(...)把父类需要的参数传进去。如果父类有无参构造可以省略但显式写出来更清晰。5.2 方法重写写成重载参数列表不一致易漏点想重写父类方法结果参数类型或个数写错变成了重载。为什么漏重载和重写的语法很像都是方法名相同区别在参数列表和返回类型。编译器不会报错因为重载是合法的但多态调用时不会执行子类方法。怎么补重写时强制加Override注解编译器会帮你检查签名是否匹配父类。实验 3 和实验 4 里每个重写方法都加上能省掉大量调试时间。5.3 接口变量误当实例变量用易漏点在接口里写int count 0;以为是个可修改的实例变量。为什么漏接口里的变量默认是public static final也就是常量赋值后不能改。编译时不会报错但运行到修改语句时直接抛异常。怎么补接口只定义方法签名和常量需要实例变量就放到抽象类或实现类里。实验 4 里如果需要在接口中共享状态改用抽象类。5.4 finally 块里写 return 覆盖返回值易漏点在finally块里写了return语句导致try块里的返回值被覆盖。为什么漏finally的执行优先级高于try的returnJVM 会先执行finally再返回如果finally里有return就直接从那里返回了。怎么补finally块只做资源释放和清理绝对不写return、break、continue。实验 5 里检查一遍所有finally块确保只有close或日志输出。5.5 文件读写忘关流或编码不一致易漏点用FileWriter写中文读出来是乱码或者写完不关流文件内容不完整。为什么漏默认编码取决于操作系统写入和读取时编码不一致就会乱码。不关流则缓冲区数据没有刷到文件里。怎么补统一用OutputStreamWriter指定 UTF-8并且用 try-with-resources 自动关流。实验 6 里所有文件操作都套上这两条规则。6. 复习清单与查漏补缺六次实验的过关自测方法复习这套实验代码最有效的方式不是从头到尾重读一遍而是按模块做自测。下面这张清单可以直接抄作业每过一条打个勾哪条卡住了就回到对应实验去补。模块自测问题对应实验类与对象能否默写出一个带无参和带参构造的类实验 1封装getter/setter 是否做了参数校验toString 格式是否统一实验 2继承子类构造是否显式调用了 super重写方法是否加了 Override实验 3多态能否说清抽象类和接口的选择标准实验 4异常自定义异常继承 Exception 还是 RuntimeExceptionfinally 里有没有 return实验 5集合与 IO文件读写是否指定了 UTF-8是否用了 try-with-resources实验 6自测的时候建议用「白纸默写」法关掉代码拿一张白纸把每个实验的核心类和方法签名默写出来。写不出来的地方就是知识盲区立刻回去翻代码对照。这个方法比反复看代码有效得多因为看代码是输入默写是输出输出才能暴露真实掌握程度。还有一个查漏补缺的技巧是「改错法」把实验代码里故意改错几处比如去掉super(...)、把Override删掉、在finally里加return然后看编译器报什么错、运行时抛什么异常。梳理下来会发现很多易错点只有亲手制造一次错误才能真正记住。从那以后我每次复习这套实验都强制自己先默写再对照最后用改错法过一遍易错点。希望这份梳理能帮到你把六次实验串成一条线而不是六个孤立的压缩包。本文还有配套的精品资源点击获取