
本文讲解如何通过继承与多态,将不同子类(Lindt、Baravelli、ChocoAmor)的糖果盒对象统一存入父类类型 ArrayList,并正确打印其内容——关键在于合理设计类结构、重写 toString() 方法,并避免语法与逻辑错误。
本文讲解如何通过继承与多态,将不同子类(lindt、baravelli、chocoamor)的糖果盒对象统一存入父类类型 arraylist,并正确打印其内容——关键在于合理设计类结构、重写 `tostring()` 方法,并避免语法与逻辑错误。
要实现一个能容纳多种具体糖果盒(如 Lindt、Baravelli、ChocoAmor)的礼品袋(CandyBag),核心思路是:利用面向对象的多态性——所有子类均继承自 CandyBox,因此可统一用 ArrayList<candybox></candybox> 存储,再通过重写的 toString() 方法实现个性化输出。
首先,修正原始代码中的关键问题:
- ❌
CandyBag不应继承CandyBox:CandyBag是“容器”,而CandyBox是“被装的物品”,二者是 has-a(组合)关系,不是 is-a(继承)关系; - ❌ 字段不能在类体中直接执行实例化和
add()操作(Java 不允许在声明处调用方法); - ❌
printArray方法参数类型错误(应为ArrayList<candybox></candybox>,且不应传入未定义变量candybag); - ❌
Candybox拼写错误(应为CandyBox),ChocAmor类名与问题中ChocoAmor不一致; - ✅ 必须为每个子类重写
toString(),否则默认打印内存地址(如Lindt@1b6d3586)。
✅ 正确实现如下:
// 父类:所有糖果盒的共同基类
class CandyBox {
protected String flavor;
protected String origin;
public CandyBox(String flavor, String origin) {
this.flavor = flavor;
this.origin = origin;
}
// 通用 toString —— 可被子类 super 调用
@Override
public String toString() {
return String.format("CandyBox[flavor=%s, origin=%s]", flavor, origin);
}
}
// 子类:Lindt 盒(含 height, width)
class Lindt extends CandyBox {
private double height, width;
public Lindt(String flavor, String origin, double height, double width) {
super(flavor, origin);
this.height = height;
this.width = width;
}
@Override
public String toString() {
return String.format("Lindt[%s, %s, h=%.1f, w=%.1f]", flavor, origin, height, width);
}
}
// 子类:Baravelli 盒(含 height, width)
class Baravelli extends CandyBox {
private double height, width;
public Baravelli(String flavor, String origin, double height, double width) {
super(flavor, origin);
this.height = height;
this.width = width;
}
@Override
public String toString() {
return String.format("Baravelli[%s, %s, h=%.1f, w=%.1f]", flavor, origin, height, width);
}
}
// 子类:ChocoAmor 盒(示例仅含 height,可按需扩展)
class ChocoAmor extends CandyBox {
private double height;
public ChocoAmor(String flavor, String origin, double height) {
super(flavor, origin);
this.height = height;
}
@Override
public String toString() {
return String.format("ChocoAmor[%s, %s, h=%.1f]", flavor, origin, height);
}
}
// 容器类:CandyBag(组合关系,非继承!)
import java.util.*;
class CandyBag {
private List<CandyBox> candyBag = new ArrayList<>();
// 构造时初始化三种糖果盒(可封装为独立方法)
public CandyBag() {
candyBag.add(new Lindt("Cherry", "Austria", 20.0, 5.4));
candyBag.add(new Baravelli("Grape", "Italy", 6.7, 8.7));
candyBag.add(new ChocoAmor("Coffee", "France", 5.5));
}
// 打印所有糖果盒(使用增强 for 循环 + 多态 toString)
public void printContents() {
System.out.println("? CandyBag Contents:");
for (CandyBox box : candyBag) {
System.out.println(box); // 自动调用对应子类的 toString()
}
}
}在 main 方法中使用:
public class Main {
public static void main(String[] args) {
CandyBag gift = new CandyBag();
gift.printContents();
}
}输出示例:
? CandyBag Contents: Lindt[Cherry, Austria, h=20.0, w=5.4] Baravelli[Grape, Italy, h=6.7, w=8.7] ChocoAmor[Coffee, France, h=5.5]
? 关键注意事项:
- ✅ 始终使用
List<candybox></candybox>接口类型而非ArrayList具体类型,提高扩展性; - ✅ 所有子类
toString()必须@Override并返回有意义字符串,这是多态打印的基础; - ✅ 初始化逻辑应放在构造方法或专用
init()方法中,禁止在字段声明处执行操作; - ✅ 若需动态添加(如用户输入),可提供
addCandyBox(CandyBox box)方法; - ✅ 如需类型识别,可用
instanceof或访问者模式,但本场景无需——多态已足够。
通过以上设计,你获得了一个类型安全、可扩展、语义清晰的糖果礼品袋系统,完美体现 Java 继承、多态与组合的设计思想。


















