Java:无需getName(),如何在ArrayList输出中显示形状对象名称
替代
getName()获取对象标识的几种实用方案 嘿,我来给你几个不用getName()也能实现目标输出的方案,结合你的场景选最适合的就行:
1. 给子类添加实例名称字段(最灵活)
直接在Rectangle和Circle子类里新增一个name字段,创建对象时手动传入标识(比如"rectangle 1"),然后在toString()里拼接这个名称。这种方式完全自定义,想给对象起啥名都可以。
示例代码:
public class Rectangle extends Shapes { private final String name; private double width; private double height; // 构造函数传入名称 public Rectangle(String name, double width, double height) { this.name = name; this.width = width; this.height = height; } @Override public double getArea() { return width * height; } @Override public String toString() { return name + " has an area of : " + getArea(); } } // 创建对象时指定名称 Shapes rectangle1 = new Rectangle("rectangle 1", 5, 3); Shapes circle1 = new Circle("circle 1", 4);
2. 子类静态计数器自动生成编号(无需手动传参)
如果不需要自定义名称,只是想要"rectangle 1"、"circle 2"这种连续编号,可以在每个子类里加一个静态计数器,构造对象时自动递增编号,toString()里用类名+编号拼接。
示例代码:
public class Circle extends Shapes { private static int circleCount = 0; // 静态计数器,所有Circle实例共享 private final int instanceId; private double radius; public Circle(double radius) { this.instanceId = ++circleCount; // 构造时自增编号 this.radius = radius; } @Override public double getArea() { return Math.PI * radius * radius; } @Override public String toString() { // 用类名小写+编号生成标识 return "circle " + instanceId + " has an area of : " + getArea(); } } // 创建对象时不用传名称,自动生成编号 Shapes circle1 = new Circle(4); Shapes circle2 = new Circle(6);
⚠️ 注意:如果是多线程环境创建对象,记得给计数器的自增操作加同步(比如synchronized),避免编号混乱。
3. 结合类名+对象唯一标识(简单快速)
如果不需要连续编号,只是想区分不同实例,可以用对象的类名加上System.identityHashCode(this)生成唯一标识,这种方式不用额外字段或计数器,代码最简洁。
示例代码:
@Override public String toString() { String shapeName = this.getClass().getSimpleName().toLowerCase(); return shapeName + " " + System.identityHashCode(this) + " has an area of : " + getArea(); }
输出会类似:rectangle 123456 has an area of : 15,虽然不是连续数字,但能保证每个实例标识唯一。
4. 父层统一管理类型与编号(优雅复用)
如果想避免子类重复编写编号逻辑,可以在Shapes父类里定义形状类型枚举和对应计数器,子类构造时指定类型,父类自动分配编号。
示例代码:
// 父类Shapes public abstract class Shapes { public enum ShapeType { RECTANGLE, CIRCLE } private static Map<ShapeType, Integer> typeCounter = new HashMap<>(); private final String instanceName; protected Shapes(ShapeType type) { // 初始化对应类型的计数器 typeCounter.putIfAbsent(type, 0); int count = typeCounter.get(type) + 1; typeCounter.put(type, count); // 生成实例名称 this.instanceName = type.name().toLowerCase() + " " + count; } public abstract double getArea(); @Override public String toString() { return instanceName + " has an area of : " + getArea(); } } // 子类Rectangle public class Rectangle extends Shapes { private double width; private double height; public Rectangle(double width, double height) { super(ShapeType.RECTANGLE); // 指定类型 this.width = width; this.height = height; } @Override public double getArea() { return width * height; } }
这种方式把编号逻辑统一放在父类,子类只需要关注自身的面积计算,代码复用性更强。
内容的提问来源于stack exchange,提问作者RogerDodger
相关产品推荐
相关产品推荐

