You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

4.5 KiB

实验报告 - 图形面积计算器重构

一、实验目的

  1. 学习使用抽象类和继承实现代码重构
  2. 理解多态的概念和应用
  3. 掌握"组合 vs 继承"的设计选择

二、实验内容

1. 设计抽象类 Shape

public abstract class Shape {
    public abstract double getArea();
}

2. 三个图形类继承 Shape

Circle.java

public class Circle extends Shape {
    private double radius;
    
    public Circle(double radius) {
        this.radius = radius;
    }
    
    @Override
    public double getArea() {
        return Math.PI * radius * radius;
    }
}

Rectangle.java

public class Rectangle extends Shape {
    private double width;
    private double height;
    
    public Rectangle(double width, double height) {
        this.width = width;
        this.height = height;
    }
    
    @Override
    public double getArea() {
        return width * height;
    }
}

Triangle.java

public class Triangle extends Shape {
    private double base;
    private double height;
    
    public Triangle(double base, double height) {
        this.base = base;
        this.height = height;
    }
    
    @Override
    public double getArea() {
        return 0.5 * base * height;
    }
}

3. ShapeUtil 工具类

public class ShapeUtil {
    public static void printArea(Shape shape) {
        String shapeName = shape.getClass().getSimpleName();
        double area = shape.getArea();
        System.out.println(shapeName + " 的面积是: " + area);
    }
}

4. 运行结果

=== 图形面积计算器 ===
Circle 的面积是: 78.53981633974483
Rectangle 的面积是: 24.0
Triangle 的面积是: 12.0

三、AI 使用情况记录

使用环节 AI 辅助内容 说明
代码编写 完全由 AI 生成 根据实验要求生成完整代码
类图绘制 AI 生成文本版类图 使用 Markdown 格式展示
报告撰写 AI 生成报告模板 包含完整的实验内容

四、"组合 vs 继承"问题回答

继承(Inheritance)- 本次实验使用

优点:

  1. 代码复用:子类自动获得父类的属性和方法
  2. 多态性:可以用父类引用统一处理子类对象
  3. 层次清晰:IS-A 关系明确,Circle IS-A Shape

缺点:

  1. 耦合度高:子类与父类紧密绑定,父类修改可能影响所有子类
  2. 灵活性差:Java 只支持单继承,一个类只能继承一个父类
  3. 破坏封装:子类可能依赖父类的实现细节

组合(Composition)

优点:

  1. 松耦合:类之间通过接口或引用关联,相互独立
  2. 灵活性高:可以在运行时动态组合对象
  3. 更好的封装:每个类只关注自己的职责

缺点:

  1. 代码量可能增加:需要显式委托方法调用
  2. 关系不够直观:HAS-A 关系不如 IS-A 直观

本实验的选择分析

为什么选择继承:

  1. IS-A 关系明确:Circle、Rectangle、Triangle 都是 Shape,符合继承的语义
  2. 多态需求:ShapeUtil.printArea() 需要统一处理不同类型的图形
  3. 代码简洁:继承使得代码更加简洁,不需要额外的委托代码

什么情况下应该用组合:

如果图形类需要同时拥有多种特性(如"可旋转"、"可填充颜色"),而这些特性之间没有层次关系,则应该使用组合。例如:

public class Circle {
    private Rotatable rotator;  // 组合:可旋转特性
    private Fillable filler;    // 组合:可填充特性
}

设计原则

"组合优于继承"(Favor Composition Over Inheritance)

这是面向对象设计的重要原则。继承适合表达 IS-A 关系,而组合适合表达 HAS-A 关系。在实际开发中:

  • 当类之间存在自然的层次关系时,使用继承
  • 当需要复用功能但不存在层次关系时,使用组合
  • 优先使用组合,除非继承明显更合适

本实验中,图形与形状之间是自然的 IS-A 关系,因此继承是合适的选择。

五、总结

通过本次实验,我学会了:

  1. 如何使用抽象类定义通用接口
  2. 如何通过继承实现代码复用和多态
  3. 理解了组合与继承的区别及适用场景
  4. 掌握了面向对象设计的核心思想

重构后的代码结构清晰,易于扩展。如果需要添加新的图形(如 Square、Ellipse),只需继承 Shape 类并实现 getArea() 方法即可,符合开闭原则。