使用组合而非继承时,数组应存储何种类型?
组合模式下如何存储不同类的实例到同一数组中
在继承场景中,我们可以通过父类数组直接存储子类实例,但在组合模式下,Player和Monster只是持有Entity字段,并无继承关系,无法直接存入Entity[]数组。要解决这个问题,有以下几种可行方案:
方案1:定义共同接口(推荐)
创建一个包含获取Entity方法的接口,让Player和Monster都实现该接口,数组使用接口类型,既保证类型安全,又符合面向接口编程的原则。
// 定义共同接口 interface HasEntity { Entity getEntity(); } class Entity { public int id; public Entity() { this.id = 0; } } class Player implements HasEntity { Entity entity; public Player() { this.entity = new Entity(); this.entity.id = 1; } @Override public Entity getEntity() { return entity; } } class Monster implements HasEntity { Entity entity; public Monster() { this.entity = new Entity(); this.entity.id = 2; } @Override public Entity getEntity() { return entity; } } public class Main { public static void main(String[] args) { Player player = new Player(); Monster monster = new Monster(); HasEntity[] entities = new HasEntity[2]; entities[0] = player; entities[1] = monster; // 通过接口方法统一获取Entity System.out.println(entities[0].getEntity().id); // 输出1 System.out.println(entities[1].getEntity().id); // 输出2 } }
方案2:使用Object数组(不推荐)
Java中所有类都继承自Object,因此可以用Object[]存储任意对象,但这种方式会丢失类型信息,需要强制转换才能访问内部字段,容易引发ClassCastException,类型安全性差,仅适合临时场景。
class Entity { public int id; public Entity() { this.id = 0; } } class Player { Entity entity; public Player() { this.entity = new Entity(); this.entity.id = 1; } } class Monster { Entity entity; public Monster() { this.entity = new Entity(); this.entity.id = 2; } } public class Main { public static void main(String[] args) { Player player = new Player(); Monster monster = new Monster(); Object[] entities = new Object[2]; entities[0] = player; entities[1] = monster; // 必须强制转换才能访问内部字段 System.out.println(((Player) entities[0]).entity.id); // 输出1 System.out.println(((Monster) entities[1]).entity.id); // 输出2 } }
方案3:定义抽象父类
创建一个抽象类作为Player和Monster的父类,统一类型的同时,可以在抽象类中封装通用逻辑,适合需要共享部分实现的场景。
abstract class EntityHolder { protected Entity entity; // 提供统一的获取Entity方法 public Entity getEntity() { return entity; } } class Entity { public int id; public Entity() { this.id = 0; } } class Player extends EntityHolder { public Player() { this.entity = new Entity(); this.entity.id = 1; } } class Monster extends EntityHolder { public Monster() { this.entity = new Entity(); this.entity.id = 2; } } public class Main { public static void main(String[] args) { Player player = new Player(); Monster monster = new Monster(); EntityHolder[] entities = new EntityHolder[2]; entities[0] = player; entities[1] = monster; System.out.println(entities[0].getEntity().id); // 输出1 System.out.println(entities[1].getEntity().id); // 输出2 } }
总结
- 优先选择方案1(接口),灵活性高、类型安全,符合面向对象设计原则。
- 方案3(抽象类)适合需要共享通用逻辑的场景。
- 方案2(Object数组)仅作为临时妥协方案,不推荐在生产代码中使用。
内容的提问来源于stack exchange,提问作者cardiaque66
相关产品推荐
相关产品推荐

