您可以将对象转换为实现接口的对象吗?现在,我正在构建一个GUI,我不想一遍又一遍地重写确认/取消代码(确认弹出窗口)。
所以,我要做的是编写一个传递它所使用的类的类,并告诉类用户是否按下确认或取消。 类总是实现某个接口。
代码:
class ConfirmFrame extends JFrame implements ActionListener
{
JButton confirm = new JButton("Confirm");
JButton cancel = new JButton("Cancel");
Object o;
public ConfirmFrame(Object o)
{
// Irrelevant code here
add(confirm);
add(cancel);
this.o = (/*What goes here?*/)o;
}
public void actionPerformed( ActionEvent evt)
{
o.actionPerformed(evt);
}
}
我意识到我可能过于复杂了,但是现在我遇到了这个问题,我真的想知道你是否可以将一个对象转换为另一个实现某个接口的对象。
答案 0 :(得分:3)
您可以在类型层次结构中向上或向下投射对象;有时这是安全的,有时却不是。如果您尝试将变量转换为不兼容的类型(即试图说服编译器它不是它的东西),您将获得运行时异常(即错误)。转到更一般的类型(比如将ActionListener
更改为Object
)称为upcasting,并且总是安全的,假设您要转换的类是当前类的祖先之一(而Object
是Java中所有东西的祖先。转到更具体的类型(例如从ActionListener
转换为MySpecialActionListener
)仅适用于您的对象 是更具体类型的实例。
所以,在你的情况下,听起来你要做的就是说ConfirmFrame实现了ActionListener接口。我假设该界面包括:
public void actionPerformed( ActionEvent evt);
然后在这里,在您的虚拟方法实现中,您希望将evt委托给传递给构造函数的任何对象o
。这里的问题是Object
没有名为actionPerformed
的方法;只有一个更专业的类(在这种情况下,像你的ActionListener
类的ConfirmFrame
的实现)会拥有它。所以你可能想要的是该构造函数采用ActionListener
而不是Object
。
class ConfirmFrame extends JFrame implements ActionListener
{
JButton confirm = new JButton("Confirm");
JButton cancel = new JButton("Cancel");
ActionListener a;
public ConfirmFrame(ActionListener a)
{
// Irrelevant code here
add(confirm);
add(cancel);
this.a = a;
}
public void actionPerformed( ActionEvent evt)
{
a.actionPerformed(evt);
}
}
当然,比“o”或“a”更多的解释性变量名称可能会帮助您(以及阅读此内容的任何人)理解为什么要将ActionListener传递给另一个ActionListener。
答案 1 :(得分:0)
当然你可以 - 通常的铸造语法适用。您甚至可以将参数类型声明为接口,而不是Object
。
编辑:当然,变量的类型也需要是接口,或者你可以在调用方法时将其强制转换,即。
ActionPerformer o;
...
this.o = (ActionPerformer)o;
或
((ActionPerformer)this.o).actionPerformed(evt);
答案 2 :(得分:0)
以上答案的用法示例::)
class MyFrame extends Frame{
ActionListener confirmListener = new ActionListener (){
//implementation of the ActionListener I
public void actionPerformed(ActionEvent e){
if ( e.getActionCommand().equals("Cancel")){
// do Something
}
else if(e.getActionCommand().equals("Confirm")){
// do Something
}
}
};
ConfirmFrame confirmDialog = new ConfirmDialog(confirmListener);
//code that uses the ConfirmFrame goes here....
}