简体   繁体   English

您可以将对象强制转换为实现接口的对象吗? (JAVA)

[英]Can you cast an object to one that implements an interface? (JAVA)

Can you cast an object to one that implements an interface? 您可以将对象强制转换为实现接口的对象吗? Right now, I'm building a GUI, and I don't want to rewrite the Confirm/Cancel code (A confirmation pop-up) over and over again. 现在,我正在构建一个GUI,并且我不想一遍又一遍地重写Confirm / Cancel代码(确认弹出窗口)。

So, what I'm trying to do is write a class that gets passed the class it's used in and tells the class whether or not the user pressed Confirm or Cancel. 因此,我想做的是编写一个类,该类传递它使用的类 ,并告诉该类用户是否按下了Confirm或Cancel。 The class always implements a certain interface. 该类始终实现特定的接口。

Code: 码:

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);
    }
}

I realize that I'm probably over-complicating things, but now that I've run across this, I really want to know if you can cast an object to another object that implements a certain interface. 我意识到自己可能使事情复杂化了,但是现在我已经碰到了这一点,我真的很想知道是否可以将一个对象强制转换为实现某个接口的另一个对象。

You can cast objects either up or down the type hierarchy; 您可以在类型层次结构中向上或向下转换对象。 sometimes this is safe, and sometimes it isn't. 有时这很安全,有时却不是。 If you attempt to cast a variable to an incompatible type (ie try to convince the compiler it's something it's not), you'll get a runtime exception (ie error). 如果您尝试将变量强制转换为不兼容的类型(即尝试说服编译器,但并非如此),则会得到运行时异常(即错误)。 Going to a more general type (like changing an ActionListener into an Object ) is called upcasting, and is always safe, assuming the class you're casting to is one of the ancestors of your current class (and Object is an ancestor of everything in Java). 转到更通用的类型(例如将ActionListener更改为Object )称为向上转换,并且总是安全的,假设要转换为的类是当前类的祖先之一(而Object是其中所有类的祖先) Java)。 Going to a more specific type (like casting from ActionListener to MySpecialActionListener ) only works if your object actually is an instance of the more specific type. 仅当您的对象实际上该特定类型的实例时,才能使用更特定的类型(例如从ActionListenerMySpecialActionListener )。

So, in your case, it sounds like what you're trying to do is say that ConfirmFrame implements the interface ActionListener. 因此,就您而言,这听起来像您要尝试的是说ConfirmFrame实现了ActionListener接口。 I assume that that interface includes: 我认为该接口包括:

public void actionPerformed( ActionEvent evt);

And then here, in your implementation of that virtual method, you want to delegate the evt to whatever object o was passed into the constructor. 然后,在此虚拟方法的实现中,您想要将evt委托给传递给构造函数的任何对象o The problem here is that Object doesn't have a method called actionPerformed ; 这里的问题是Object没有名为actionPerformed的方法。 only a more specialized class (in this case, an implementation of ActionListener like your ConfirmFrame class) would have it. 只有更专业的类(在这种情况下,是ActionListener的实现,例如ConfirmFrame类)才具有它。 So what you probably want is for that constructor to take an ActionListener instead of an Object . 因此,您可能希望该构造函数采用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);
    }
}

Of course, more explanatory variable names than "o" or "a" would probably help you (and anyone else reading this) understand why you're passing an ActionListener into another ActionListener. 当然,比“ o”或“ a”更多的解释性变量名称可能会帮助您(以及其他阅读此书的人)理解为什么要将ActionListener传递给另一个ActionListener。

Of course you can - the usual syntax for casting applies. 当然可以-适用常规的转换语法。 You could even declare the parameter type as the interface rather than Object . 您甚至可以将参数类型声明为接口而不是Object

Edit: of course, the type of the variable also needs to be the interface or, alternatively you can cast it when calling a method on it, ie. 编辑:当然,变量的类型也需要是接口,或者,也可以在调用方法时将其强制转换。

ActionPerformer o;
...
this.o = (ActionPerformer)o;

or 要么

((ActionPerformer)this.o).actionPerformed(evt);

Example Usage of the Above answer: :) 上述答案的示例用法::)

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....

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM