允许Java方法调用参数对象的子类的方法?

时间:2011-04-17 03:25:17

标签: java

我正在完成一项小型大学任务。由于厌倦了编写三行代码来添加按钮,我写了一个小实用函数:

private JButton addButton(Container container, String text) {

    JButton button = new JButton(text);
    button.addActionListener(this);
    container.add(button);

    return button;
}

然后当然来了实用工具方法来添加textFields:

private JTextField addInput(Container container, int width) {

    JTextField input = new JTextField(width);
    input.addActionListener(this);
    container.add(input);

    return input;
}

如您所见,它们几乎完全相同。所以我尝试通过一个强大的方法来减少行数,这些方法可以为任何其他东西添加任何东西。

private Component addComponent(Container container, Component component) {

    component.addActionListener(this);
    container.add(component);

    return component;
}

现在,我必须承认,我开始认为这些超小实用功能可能有点荒谬。

然而,无论如何,我所有强大的addComponent方法都不起作用。而是抱怨Component没有ActionListeners

我能看到的唯一方法就是拥有MyJButtonMyJTextField,这两者都继承自MyComponent并具有addActionListener方法。最简单的原始目标和消除重复被抛出窗外?

如何/应该如何做?我是Java新手和严格打字的东西!

3 个答案:

答案 0 :(得分:1)

有几种方法。如果您确定自己的方法addComponent仅对JTextFieldJButton参数有效,则可以进行显式转换

 if (component instanceof JButton){
  ((JButton)component).addActionListener(this); 
 }
 else if (component instanceof JTextField){
  ((JTextField)component).addActionListener(this);
 }

不是很优雅,不是很好的练习,但它可能就足够了。

如果你想在addActionListener拥有该方法的情况下调用Component,则可以使用反射 - 但我怀疑这对你的目标来说太过分了。

PS:如果你对它更清楚,这将等同于第二行:

  JButton button = (JButton)component; // explicit cast -we know for sure that this is a JButton 
  button.addActionListener(this); 

答案 1 :(得分:1)

问题是没有公开

的界面
addActionListener(ActionListener l)

如果有的话,你可以做到

public <T extends Component & ActionListenable> Component addComponent(Container container, T component) {

    component.addActionListener(this);
    container.add(component);

    return component;
}

假设虚假的ActionListenable是前面提到的界面。

答案 2 :(得分:1)

我会说你当前的方法(一堆类似的辅助方法)和你一样好。

有些东西不够优雅,而且你无能为力。

尝试组合这些方法的风险(与@ leonbloy的答案一致)是您将静态类型安全性替换为运行时类型安全性;当类型转换失败时,ClassCastExceptions ......或更糟。


从语言学的角度来看,所需要的是一种应用程序使用额外的方法(或方法)“装饰”现有类层次结构的方法,并且通过多态调度来调用方法,就像使用普通实例一样方法

这可以使用Decorator模式进行模拟,但它需要一些相当重量级的基础结构......如果类层次结构没有支持内置模式的钩子。