未调用子类的方法(正确)

时间:2016-05-22 21:14:44

标签: java inheritance

我有一个课程" FileButton "。它的目的是将文件链接到JButton, FileButton 继承自 JButton 。子类从这个继承,用链接到按钮的文件做有用的东西。

Class JingleCardButton 是其中一个子类。当使用方法" playSound()"单击按钮时,此子类有一个方法可以播放链接到 JingleCardButton 的铃声。此方法在从 FileButton 继承的其他子类中不可用

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

由于每种都需要存储它的所有内容,因此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,一个装有JingleCardButtons的2D数组。使用GUI将mp3文件添加到按钮(创建卡时没有自动链接的文件)之后。

现在我应该能够(我想是这样的话)在 JingleCard ButtonGrid的某个地方播放分配了gui的叮当声到 JingleCardButton

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

我不知道为什么,但是当在Netbeans中编译时,这会产生错误......根据Netbeans,方法 PlaySound()无法在类中找到 FileButton 即可。 (这是真的,因为它在儿童班 JingleCardButton )。

造成这个问题的原因是什么?我确定 buttonGrid 包含 JingleCardButton 对象,并且调用 playSound()应该可以正常工作。我不知道出了什么问题。

(提到的一些类也实现了ActionListener和Serializable)

1 个答案:

答案 0 :(得分:1)

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

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

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

...但是这会导致代码变脏,代码很脆弱且容易被破坏。

更好的是甚至没有子类型JButton,因为你似乎不想改变JButton的固有属性,而是在按下它时的行为。此行为不是由按钮本身决定的,而是由它设置的Action,或者已添加的ActionListeners。出于这个原因,我强烈建议您创建扩展AbstractAction而不是JButton的类,除非有其他JButton行为,与您的动作侦听器行为无关的行为,您希望修改它们。