You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

向ArrayList<Shape>添加子类对象报错的技术求助

问题根源

最核心的问题是**Shape.Rectangle没有继承Shape类**。虽然你把它定义成了Shape的静态内部类,但这只是代码位置上的嵌套,没有继承关系的话,编译器不认它是Shape类型,自然塞不进ArrayList<Shape>里。

另外,改成ArrayList<Object>后,从列表里取出来的是Object对象,而Object本身没有getName()和area()方法,调用时必然报错。


修复步骤

1. 让图形子类继承Shape抽象类

所有图形子类(Rectangle、Circle、Triangle)都要继承Shape,这样它们才是Shape的子类,能被添加到ArrayList<Shape>中。而且Shape已经定义了name属性和对应的get/set方法,子类不用重复编写,直接复用即可,只需要实现抽象的area()方法,加上自己独有的属性(比如矩形的长和宽)。

修正后的Rectangle类:

/**
 * Rectangle子类
 */
public static class Rectangle extends Shape {
    
    /**
     * 矩形独有的实例变量:长、宽
     */
    private Double length, width;
    
    /**
     * 默认构造方法
     */
    public Rectangle() {
        super("Rectangle"); // 调用父类构造方法设置名称
        this.length = 1.0;
        this.width = 1.0;
    }
    
    /**
     * 带参构造方法
     */
    public Rectangle(String name, Double length, Double width) {
        super(name); // 调用父类构造方法设置名称
        this.length = length;
        this.width = width;
    }
    
    // 只保留矩形独有的get/set方法
    public Double getLength() {
        return length;
    }
    
    public void setLength(Double newLength) {
        this.length = newLength;
    }
    
    public Double getWidth() {
        return width;
    }
    
    public void setWidth(Double newWidth) {
        this.width = newWidth;
    }
    
    /**
     * 实现父类的抽象area方法
     */
    @Override
    public double area() {
        return this.length * this.width;
    }
    
    /**
     * 修正equals方法,正确比较矩形对象
     */
    @Override
    public boolean equals(Object obj) {
        if (this == obj) return true;
        if (obj == null || getClass() != obj.getClass()) return false;
        Rectangle rectangle = (Rectangle) obj;
        // 复用父类的name属性进行比较
        return getName().equals(rectangle.getName()) && length.equals(rectangle.length) && width.equals(rectangle.width);
    }
    
    /**
     * 优化toString方法
     */
    @Override
    public String toString() {
        return super.toString() + ", 长: " + length + ", 宽: " + width;
    }
}

Circle和Triangle类也要照这个逻辑修改:继承Shape,实现area方法,去掉重复的name相关代码。

2. 修正Shape类的equals方法

原Shape的equals方法逻辑完全错误——它把传入的对象和字符串(this.name)直接用==比较,这永远不会成立。正确的equals应该先判断对象是否是同一实例,再判断类型,最后比较属性:

@Override
public boolean equals(Object obj) {
    if (this == obj) return true;
    if (obj == null || getClass() != obj.getClass()) return false;
    Shape shape = (Shape) obj;
    return name.equals(shape.name);
}

3. 修复Scanner读取的换行问题

原create方法里,用scan.nextLine()读取shapeType后,调用scan.nextDouble()只会读取数字,不会消耗后面的换行符,导致下一次scan.nextLine()读到空字符串,逻辑混乱。所以每次读取完double后,要加一行scan.nextLine()来消耗换行符:

修正后的create方法:

public static void create(ArrayList<Shape> list) throws FileNotFoundException {
    File dataFile = new File("./src/shape/dataFile.txt");
    Scanner scan = new Scanner(dataFile);
    
    while (scan.hasNextLine()) {
        String shapeType = scan.nextLine().trim();
        if (shapeType.isEmpty()) continue; // 跳过空行
        
        if (shapeType.equals("Rectangle")) {
            String name = scan.nextLine().trim();
            Double length = scan.nextDouble();
            Double width = scan.nextDouble();
            scan.nextLine(); // 消耗nextDouble后的换行符
            list.add(new Shape.Rectangle(name, length, width));
        }
        else if (shapeType.equals("Circle")) {
            String name = scan.nextLine().trim();
            Double radius = scan.nextDouble();
            scan.nextLine(); // 消耗换行符
            list.add(new Shape.Circle(name, radius));
        }
        else if (shapeType.equals("Triangle")) {
            String name = scan.nextLine().trim();
            Double side1 = scan.nextDouble();
            Double side2 = scan.nextDouble();
            Double side3 = scan.nextDouble();
            scan.nextLine(); // 消耗换行符
            list.add(new Shape.Triangle(name, side1, side2, side3));
        }
    }
    scan.close();
}

总结

做完这些修改后,ArrayList<Shape>就能正常添加各个图形子类对象了,display方法也能正确调用父类的getName()和子类实现的area()方法。另外记得Circle和Triangle类也要做和Rectangle一样的继承修正,不然还是会报错。

内容的提问来源于stack exchange,提问作者OhmsLaw

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 21:24:49