Java中如何调用数组内不同类实例的play方法?
问题:将乐器实例存入数组后,如何访问它们的play方法?
我编写了以下代码,试图把Drum和Xylophone实例存入Orchestra的数组中,但存入后无法调用它们的play方法,存入前却可以正常调用。
Main类
public class Main { public static void main(String[] args) { Orchestra orchestra = new Orchestra(); Drum drum = new Drum(); Xylophone xylophone = new Xylophone(); //---------------------------------- drum.sendToOrchestra(); xylophone.sendToOrchestra(); } }
Drum类
public class Drum{ public void play(String note){ System.out.println("Playing... drums (note " + note + ")"); } public void sendToOrchestra(){ Orchestra orchestra = new Orchestra(this); } }
Xylophone类
public class Xylophone{ public void play(String note){ System.out.println("Playing... xylophone (note " + note + ")"); } public void sendToOrchestra(){ Orchestra orchestra = new Orchestra(this); } }
Orchestra类
public class Orchestra { static Object[] instrumentsArray = new Object[2]; public Orchestra(){ } public Orchestra(Xylophone xylophone){ // this works: xylophone.play() instrumentArray[0] = xylophone; // but this does not: instrumentsArray[0].play() } public Orchestra(Drum drum){ // this works: drum.play() instrumentArray[1] = drum; // but this does not: instrumentsArray[1].play() } public void playInstruments(){ // here is where I will iterate through the instrumentsArray, and make all elements inside it: .play() } }
解决方案
核心问题是你用Object[]存储实例,而Object类本身没有play方法。Java中处理这种多态场景的标准方案是定义统一接口,让所有乐器类实现该接口,这样数组就能用接口类型声明,直接调用接口方法。
步骤1:定义Instrument接口
创建一个包含play方法的接口,作为所有乐器类的统一规范:
public interface Instrument { void play(String note); }
步骤2:修改乐器类实现接口
让Drum和Xylophone类实现Instrument接口,同时优化sendToOrchestra方法,避免重复创建Orchestra实例:
public class Drum implements Instrument { @Override public void play(String note) { System.out.println("Playing... drums (note " + note + ")"); } public void sendToOrchestra(Orchestra orchestra) { orchestra.addInstrument(this); } }
public class Xylophone implements Instrument { @Override public void play(String note) { System.out.println("Playing... xylophone (note " + note + ")"); } public void sendToOrchestra(Orchestra orchestra) { orchestra.addInstrument(this); } }
步骤3:重构Orchestra类
将数组类型改为Instrument[],替换多个重载构造方法为统一的添加方法,并实现playInstruments逻辑:
public class Orchestra { private Instrument[] instrumentsArray = new Instrument[2]; private int currentIndex = 0; // 动态记录存储位置 public Orchestra() {} public void addInstrument(Instrument instrument) { if (currentIndex < instrumentsArray.length) { instrumentsArray[currentIndex] = instrument; currentIndex++; } } public void playInstruments() { String testNote = "C"; for (Instrument instrument : instrumentsArray) { if (instrument != null) { // 避免空指针异常 instrument.play(testNote); } } } }
步骤4:调整Main类调用逻辑
传入已创建的Orchestra实例,完成乐器添加后调用演奏方法:
public class Main { public static void main(String[] args) { Orchestra orchestra = new Orchestra(); Drum drum = new Drum(); Xylophone xylophone = new Xylophone(); drum.sendToOrchestra(orchestra); xylophone.sendToOrchestra(orchestra); orchestra.playInstruments(); // 触发所有乐器演奏 } }
额外优化说明
- 把
instrumentsArray从static改为实例变量,避免多个Orchestra实例共享同一数组 - 用
currentIndex动态管理存储位置,摆脱固定索引的限制 - 统一添加乐器的方法,让代码结构更简洁易维护
内容的提问来源于stack exchange,提问作者OrlandoVSilva
相关产品推荐
相关产品推荐

