You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 19:31:15