From b34afc13cc1a9fe3c8da489b7170a6f691e254c9 Mon Sep 17 00:00:00 2001 From: JiangYouhan <3080587852@qq.com> Date: Sat, 28 Mar 2026 13:31:01 +0800 Subject: [PATCH] =?UTF-8?q?=E4=B8=8A=E4=BC=A0=E6=96=87=E4=BB=B6=E8=87=B3?= =?UTF-8?q?=20'w4'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- w4/实验报告.md | 236 +++++++++++++++++++++++++++++++++++++++++++++ w4/类图.md | 73 ++++++++++++++ 2 files changed, 309 insertions(+) create mode 100644 w4/实验报告.md create mode 100644 w4/类图.md diff --git a/w4/实验报告.md b/w4/实验报告.md new file mode 100644 index 0000000..cb69e14 --- /dev/null +++ b/w4/实验报告.md @@ -0,0 +1,236 @@ +# 图形面积计算器重构 - 实验报告 + +## 一、实验概述 + +### 实验目的 +通过重构图形面积计算器,理解面向对象编程中的抽象类、继承和多态概念,比较组合与继承的优缺点。 + +### 实验背景 +原有 Circle、Rectangle、Triangle 类独立存在,无法统一处理。通过引入抽象类 Shape,实现代码的统一管理和复用。 + +--- + +## 二、AI使用情况记录 + +### 1. AI协助项目创建 +- **创建项目结构**:通过 Trae IDE 环境快速创建项目目录 +- **文件生成**:使用代码生成工具创建 6 个 Java 类文件 +- **编译运行**:使用终端工具编译和测试程序 + +### 2. AI代码协助 +- **抽象类设计**:协助设计 Shape 抽象类,包含抽象方法 getArea() +- **继承关系**:实现 Circle、Rectangle、Triangle 继承 Shape +- **多态实现**:设计 ShapeUtil 的 printArea() 方法 +- **类图绘制**:生成 UML 类图描述 + +### 3. AI功能总结 +| 功能 | 使用情况 | +|------|---------| +| 文件创建 | ✅ 自动创建 7 个文件 | +| 代码生成 | ✅ 生成完整 Java 代码 | +| 编译运行 | ✅ 自动编译和测试 | +| 文档生成 | ✅ 生成类图和报告 | + +--- + +## 三、核心设计思路 + +### 1. 抽象类 Shape 的设计 +**为什么使用抽象类**: +- 定义统一接口:所有图形都有 getArea() 方法 +- 强制子类实现:抽象方法确保每个图形都必须计算面积 +- 代码复用:共享 name 属性和 getName() 方法 + +```java +public abstract class Shape { + private String name; + + public Shape(String name) { + this.name = name; + } + + public abstract double getArea(); +} +``` + +### 2. 继承关系设计 +**Circle、Rectangle、Triangle 继承 Shape**: +- **is-a 关系**:圆是一种图形,矩形是一种图形,三角形是一种图形 +- **复用代码**:继承 name 属性,无需重复定义 +- **实现多态**:每个图形按自己的方式计算面积 + +### 3. 多态的应用 +**ShapeUtil.printArea(Shape shape)**: +- 参数是 Shape 类型 +- 可以接受 Circle、Rectangle、Triangle 任何子类 +- 自动调用对应子类的 getArea() 方法 + +--- + +## 四、组合 vs 继承 + +### 问题:组合 vs 继承,什么时候用哪个? + +### 1. 继承(Inheritance) + +**是什么**: +- 类与类之间的 is-a 关系 +- 子类继承父类的属性和方法 +- 用 extends 关键字实现 + +**本项目使用继承的原因**: +```java +// 继承关系:圆 是一种 图形 +Circle extends Shape + +// 继承关系:矩形 是一种 图形 +Rectangle extends Shape + +// 继承关系:三角形 是一种 图形 +Triangle extends Shape +``` + +**继承的优点**: +✅ 代码复用:子类自动拥有父类的属性和方法 +✅ 多态性:可以用父类类型统一处理子类 +✅ 符合自然逻辑:圆确实是一种图形 + +**继承的缺点**: +❌ 耦合度高:父类改变会影响所有子类 +❌ 破坏封装:子类可以访问父类的 protected 成员 +❌ 不灵活:继承关系在编译时确定,运行时无法改变 + +--- + +### 2. 组合(Composition) + +**是什么**: +- 类与类之间的 has-a 关系 +- 一个类包含另一个类的对象作为成员 +- 用成员变量实现 + +**组合的例子**: +```java +// 组合关系:汽车 有一个 引擎 +public class Car { + private Engine engine; // 组合 + + public Car() { + this.engine = new Engine(); + } +} + +public class Engine { + // 引擎的功能 +} +``` + +**组合的优点**: +✅ 低耦合:类之间相对独立 +✅ 灵活性:运行时可以替换组合的对象 +✅ 符合设计原则:优先使用组合而非继承 + +**组合的缺点**: +❌ 代码较多:需要显式调用组合对象的方法 +❌ 不能直接复用:无法自动继承功能 + +--- + +### 3. 选择原则:什么时候用继承,什么时候用组合? + +| 场景 | 推荐使用 | 原因 | +|------|----------|------| +| **is-a 关系**(是一种) | 继承 | 圆是一种图形,符合继承逻辑 | +| **has-a 关系**(有一个) | 组合 | 汽车有一个引擎,使用组合 | +| **需要代码复用** | 继承 | 子类可以复用父类代码 | +| **需要灵活性** | 组合 | 运行时可以动态改变 | +| **需要多态** | 继承 | 父类引用指向子类对象 | + +--- + +### 4. 本项目为什么选择继承? + +**分析**: +1. **is-a 关系明确**: + - 圆 是一种 图形 ✅ + - 矩形 是一种 图形 ✅ + - 三角形 是一种 图形 ✅ + +2. **需要多态**: + - ShapeUtil.printArea(Shape shape) 需要统一处理 + - 用 Shape 类型可以接受任何图形 + +3. **代码复用**: + - 所有图形都有 name 属性 + - 继承避免重复代码 + +**如果用组合会怎样?** +```java +// 不推荐的组合方式 +public class Circle { + private Shape shape; // 组合 + + public Circle() { + this.shape = new Shape("圆"); + } +} +``` +这样就失去了多态的优势,不适合本项目。 + +--- + +## 五、实验总结 + +### 1. 完成的工作 +✅ 创建抽象类 Shape,包含抽象方法 getArea() +✅ 让三个图形继承 Shape,实现面积计算 +✅ 编写 ShapeUtil,提供 printArea() 方法 +✅ 绘制完整的 UML 类图 +✅ 完成实验报告,记录 AI 使用情况 +✅ 回答"组合 vs 继承"问题 + +### 2. 学到的知识点 +- 抽象类的定义和使用 +- 继承关系的实现 +- 多态的实际应用 +- 组合与继承的对比 +- 面向对象设计原则 + +### 3. 代码验证结果 +程序运行成功,输出: +``` +========== 图形面积计算器测试 ========== +--- 圆形测试 --- +图形名称: 圆 +面积: 78.53981633974483 +---------------------- +--- 矩形测试 --- +图形名称: 矩形 +面积: 24.0 +---------------------- +--- 三角形测试 --- +图形名称: 三角形 +面积: 20.0 +---------------------- +========== 测试完成 ========== +``` + +--- + +## 六、反思 + +### 1. 继承的使用场景 +通过本次实验,我深刻理解了继承的适用场景: +- 当存在明确的 is-a 关系时 +- 当需要多态性时 +- 当需要代码复用时 + +### 2. 设计原则的重要性 +"优先使用组合而非继承"是重要的设计原则,但不是绝对的。关键是根据具体场景选择合适的方式。 + +### 3. AI 工具的价值 +AI 工具在代码生成、项目搭建、文档编写等方面大大提高了效率,但核心的设计思路和概念理解还需要自己掌握。 + +--- + +**实验完成日期**:2026年3月28日 diff --git a/w4/类图.md b/w4/类图.md new file mode 100644 index 0000000..acdc681 --- /dev/null +++ b/w4/类图.md @@ -0,0 +1,73 @@ +# 图形面积计算器 - 类图 + +## UML类图(文字描述) + +``` + ┌─────────────────────────┐ + │ <> │ + │ Shape │ + ├───────────────────────┤ + │ - name: String │ + ├───────────────────────┤ + │ + Shape(name: String)│ + │ + getName(): String │ + │ + getArea(): double │ + │ <> │ + └───────────┬───────────┘ + │ + ┌──────────────────────┼──────────────────────┐ + │ │ │ + ▼ ▼ ▼ +┌───────────────────┐ ┌───────────────────┐ ┌───────────────────┐ +│ Circle │ │ Rectangle │ │ Triangle │ +├───────────────────┤ ├───────────────────┤ ├───────────────────┤ +│ - radius: double │ │ - width: double │ │ - base: double │ +│ │ │ - height: double │ │ - height: double │ +├───────────────────┤ ├───────────────────┤ ├───────────────────┤ +│ + Circle(radius) │ │ + Rectangle(w,h) │ │ + Triangle(b,h)│ +│ + getRadius() │ │ + getWidth() │ │ + getBase() │ +│ + setRadius() │ │ + setWidth() │ │ + setBase() │ +│ + getArea() │ │ + getHeight() │ │ + getHeight() │ +│ @Override │ │ + setHeight() │ │ + setHeight() │ +└───────────────────┘ │ + getArea() │ │ + getArea() │ + │ @Override │ │ @Override │ + └───────────────────┘ └───────────────────┘ + +┌─────────────────────────────────┐ +│ ShapeUtil │ +├─────────────────────────────────┤ +│ + printArea(Shape shape) │ +└─────────────────────────────────┘ +``` + +## 类图说明 + +### 类关系说明 + +1. **Shape(抽象类) + - 是所有图形的父类 + - 包含抽象方法 getArea() + - 所有子类必须实现此方法 + +2. **Circle(圆) + - 继承自 Shape + - 实现圆形面积计算:π × r² + +3. **Rectangle(矩形) + - 继承自 Shape + - 实现矩形面积计算:宽 × 高 + +4. **Triangle(三角形) + - 继承自 Shape + - 实现三角形面积计算:0.5 × 底 × 高 + +5. **ShapeUtil(工具类) + - 提供静态方法 printArea() + - 参数为 Shape 类型(多态) + - 可以接受任何 Shape 的子类 + +### 继承关系符号 +- 箭头表示继承关系(is-a) +- Circle is-a Shape +- Rectangle is-a Shape +- Triangle is-a Shape