views:

78

answers:

3

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.

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

A: 

Of course you can - the usual syntax for casting applies. You could even declare the parameter type as the interface rather than 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);
Evgeny
So, uh, you would do: "this.o = (ActionListener)o;"? I tried doing that earlier, but method actionPerformed() isn't found.
DDP
Ohhhhh, wait up, Fixed. The reason it couldn't find it was b/c i initialized the Object as an Object instead of as the interface. Thanks, Evgeny :D
DDP
+1  A: 

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 (i.e. try to convince the compiler it's something it's not), you'll get a runtime exception (i.e. 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). 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.

So, in your case, it sounds like what you're trying to do is say that ConfirmFrame implements the interface 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. The problem here is that Object doesn't have a method called actionPerformed; only a more specialized class (in this case, an implementation of ActionListener like your ConfirmFrame class) would have it. So what you probably want is for that constructor to take an ActionListener instead of an 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.

Ian Varley
Thanks for the detailed explanation :D
DDP
A: 

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

}
ultrajohn