简体   繁体   中英

How to overload a method using anonymous classes in Java?

I have a class, Action, that has a method called doAction(). This method exists solely to be overwritten for each new action that I add to an action list called allActions.

public void doAction() {
    System.out.println("Overload this method.");
} 

The list of actions is being stored in the following list:

public static List<Action> allActions = new ArrayList<Action>();

and added to this list with calls like the following:

allActions.add(
    new Action(id){
        public void doAction(Word w1, Word w2) {
            //perform some action
        }
    }
);

But this code isn't working for me. When I try to access an overwritten doAction() method from the allActions list, it just performs the default method.

I suspect that the problem is that allActions is a list of Action objects, so perhaps the type is being changed away from the anonymous class when it is being added to the list, and reverting to the default method.

Any ideas on how to maintain a list of different anonymous versions of the Action class? I want to be able to call these different doAction() methods based on the id given to the actions.

By the way, this is my first time encountering anonymous classes. I think I understand the concept, but actually using them is another story.

you are using public void doAction(Word w1, Word w2) but you have public void doAction() in parent. So parent method is not overridden.

You actually are overloading the method doAction() . But I suspect you may have confused the words overload and override .

To overload a method, you use a different quantity or type of parameters. This allows the same method to do different things depending how you call it (ie with what parameters).

Information on overloading

To override a method, you use the same quantity and type of parameters, and you are required to return the same type as the overridden ( super ) method. This allows the same method to do different things depending where you call it (ie from a superclass or a subclass).

Information on overriding

public class Anonymous {
    static class Action {
        int id;
        Action(int id) {
            this.id = id;
        }
        void doAction(){
            System.out.println("Overload this method..."+ id);
        }
    }

    public static void main(String[] args) {
        ArrayList<Action> actions = new ArrayList<Action>();
        actions.add(new Action(0));
        actions.add(new Action(1){void doAction() {System.out.println("Overloading..."+ this.id);}});
        actions.add(new Action(2){void doAction() {System.out.println("Overloading..."+ this.id);}});
        for (Action a: actions) {
            a.doAction();
        }
    }
}

The code is a simple demonstration on how to maintain a list of different anonymous versions of the Action class. And it works.

The problem you had was that you didn't actually override the doAction() method. Instead you overloaded it.

When I try to access an overwritten doAction() method from the allActions list, it just performs the default method.

It was because all objects of the anonymous classes used the doAction() method inherited from the Action class rather than the doAction(Word w1, Word w2) method which you wrongly assumed had overridden the original method.

Tips: when you override some method make sure the method signatures remain consistent. One exception is that the overriding method can possibly have a return type of subtype of that of the overridden method.

You need to read up on the difference between overriding methods and overloading methods. In overloading you can have the same method name but different parameter lists and return values and have them all in the same class, if you like. In overriding you have subclasses that have exactly the same method name which is used instead of the method from the base class.

What you are probably looking for is a list of classes that all implement the same interface. For example, use an interface called Action that contains a method with no parameters and a void return type called execute(). Then create each class and have it implement this interface. Use the constructor or getters and setters to set the objects internal state prior to calling the method. The execute method just triggers what ever activities you want to happen against the state that you've already supplied. Then add these Action objects to a list of the interface type.

Now all you have to do is iterate through the list calling the execute() method for each Action reference you retrieve from the list.

But this code isn't working for me. When I try to access an overwritten doAction() method from the allActions list, it just performs the default method.

Actually, you haven't overridden the method. You have overloaded it ... and the code that is calling the method is obviously using the old method signature.

Overriding only happens if you keep the signature as the method you are trying to override; eg

new Action(id){
    public void doAction() {
        System.out.println("you just called the overload method");
    }
}

(The problem is not with your understanding of anonymous classes. It is with your understanding of the differences between overriding and overloading ... and understanding which you should be using in this context.)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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