如何正确构建CandyBag类,用不同子类对象填充ArrayList?
解决方案
核心修正:CandyBag无需继承CandyBox
CandyBag是容器类,作用是装载各类CandyBox子类对象,本身不属于糖果盒范畴,因此不需要继承CandyBox——这是你之前设计的核心问题。
步骤1:确保子类正确实现父类构造
父类CandyBox拥有私有属性flavor和origin,子类A、B、C必须通过super()显式调用父类构造方法初始化这些属性,否则会触发编译错误。以子类A为例:
class A extends CandyBox { private double height; private double radius; private double width; // 构造方法:先初始化父类属性,再初始化自身盒型参数 public A(String flavor, String origin, double height, double radius, double width) { super(flavor, origin); this.height = height; this.radius = radius; this.width = width; } @Override public double getVolume() { // 按A盒型的体积公式计算,示例用height*radius*width return height * radius * width; } }
同理实现子类B、C,各自根据盒型逻辑重写getVolume()方法。
步骤2:正确实现CandyBag类
CandyBag内部维护ArrayList<CandyBox>集合,并在构造方法中直接完成A、B、C各一个对象的初始化:
import java.util.ArrayList; import java.util.List; class CandyBag { private List<CandyBox> candyBoxes; // 构造方法:自动初始化包含A、B、C各一个实例的礼盒 public CandyBag() { candyBoxes = new ArrayList<>(); // 添加A类实例:传入口味、产地和盒型尺寸 candyBoxes.add(new A("Cherry", "Austria", 20, 5.4, 19.2)); // 添加B类实例:假设B的构造参数为口味、产地、高度、宽度 candyBoxes.add(new B("Chocolate", "Belgium", 15, 10)); // 添加C类实例:假设C的构造参数为口味、产地、半径 candyBoxes.add(new C("Lemon", "France", 8.5)); } // 获取所有糖果盒(返回副本,避免外部修改内部集合) public List<CandyBox> getCandyBoxes() { return new ArrayList<>(candyBoxes); } // 计算礼盒总体积 public double getTotalVolume() { double total = 0; for (CandyBox box : candyBoxes) { total += box.getVolume(); } return total; } }
步骤3:验证使用示例
public class Main { public static void main(String[] args) { CandyBag giftBag = new CandyBag(); // 遍历打印所有糖果盒信息 for (CandyBox box : giftBag.getCandyBoxes()) { System.out.println("口味:" + box.getFlavor() + ",产地:" + box.getOrigin() + ",体积:" + box.getVolume()); } System.out.println("礼盒总体积:" + giftBag.getTotalVolume()); } }
注意:父类CandyBox需要提供getFlavor()和getOrigin()公共方法,用于访问私有属性。
之前编译错误的常见原因
- 子类构造未调用父类构造:若父类没有无参构造,子类必须显式通过
super(参数)初始化父类属性。 - 错误让CandyBag继承CandyBox:违背容器类的设计逻辑,还可能引发不必要的方法重写或属性冲突。
内容的提问来源于stack exchange,提问作者Aled
相关产品推荐
相关产品推荐

