我有一个类“ FileButton”。目的是将文件链接到JButton,FileButton继承自JButton。子类继承自此,通过链接到按钮的文件来做有用的事情。

类JingleCardButton是这些子类之一。该子类具有一个方法,当使用方法“ playSound()”单击按钮时,该方法可以播放链接到JingleCardButton的铃声。此方法在继承自FileButton的其他子类中不可用

另外,我有一个Card类,它在指定的JPanel上维护FileButton对象的网格。类JingleCard继承自Card,并维护JingleCardButton对象。

由于每种Card都需要存储其所有内容,因此在基类Card中声明了2D buttonGrid数组。

   protected FileButton[][] buttonGrid; //the 2d area containing all FileButton objects is declared in "Card".


这是JingleCard中的构造函数

  public JingleCard(JPanel p, int xdim, int ydim, JToggleButton editButton) {
        super(p,xdim,ydim,editButton); // calling the constructor in Card
        buttonGrid= new JingleCardButton[xdim][ydim];
        for (int row= 0; row< xdim; row++) {
          for (int column= 0; column< ydim; column++) {
            buttonGrid[row][column] = new JingleCardButton(null);
            buttonGrid[row][column].addActionListener(this);
            p.add(buttonGrid[row][column]);
        }

        p.doLayout();
    }
            p.doLayout();
        }
    }


现在,我有一个JingleCard,一个2D数组,里面装有JingleCardButtons。将mp3文件添加到按钮后(创建卡时没有文件自动链接),然后使用GUI。

现在,我应该能够(我认为是)将分配给GUI的铃声播放到JingleCard的ButtonGrid中的某个JingleCardButton上。

buttonGrid[row][column].playSound(); //syntax to play the sound is just like here: instance_of_JingleCardButton.playSound();


我不知道为什么,但是在Netbeans中编译时,这会产生一个错误...根据Netbeans,在FileButton类中找不到方法PlaySound()。 (是的,因为它在子类JingleCardButton中)。

是什么引起了这个问题?我确定buttonGrid包含JingleCardButton对象,并且调用playSound()应该可以工作。我看不出怎么了。

(提到的某些类还实现了ActionListener和Serializable)

最佳答案

您的buttonGrid是FileButton的数组,因此编译器将数组中的每个项目视为FileButton类型。现在,即使您用JingleCardButton对象填充数组,Java编译器也将只允许您对数组中的项目调用FileButton方法。您可以通过以下方式来理解基本原理,因为Java无法得知以后您可能不会使用其他子类型的FileButton对象切换出数组中的某个项目,因此它必须在安全和限制方面犯错您可以使用该变量做什么。

一种可能的解决方案是使用instanceof运算符检查变量所持有的类型对象,然后将该变量转换为JingleCardButton的类型。

if (buttonGrid[row][column] instanceof JingleCardButton) {
    ((JingleCardButton) buttonGrid[row][column]).playSound();
}


...但这会导致脏代码,代码易碎且容易损坏。

更好的是不要甚至是JButton的子类型,因为您似乎不想更改JButton的固有属性,而是希望更改其按下时的行为。此行为不是由按钮本身决定的,而是由按钮设置为什么动作或向其添加了哪些ActionListener决定的。因此,我强烈建议您创建扩展AbstractAction而不是JButton的类,除非您要修改其他JButton行为(与它的动作侦听器行为无关的行为),否则不要这样做。

关于java - 未正确调用子类中的方法,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/37379741/

10-09 06:22