如何在Java中使用匿名类重载方法?

时间:2012-12-07 05:15:45

标签: java override overloading anonymous-class

我有一个Action,它有一个名为doAction()的方法。此方法仅用于覆盖我添加到名为allActions的操作列表的每个新操作。

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

操作列表存储在以下列表中:

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

并使用以下调用添加到此列表中:

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

但是这段代码对我不起作用。当我尝试从allActions列表中访问覆盖的doAction()方法时,它只执行默认方法。

我怀疑问题是allActions是一个Action对象的列表,因此在将匿名类添加到列表中时,类型可能会从匿名类中更改,并且还原为默认方法。

有关如何维护Action类的不同匿名版本列表的任何想法?我希望能够根据给予操作的id调用这些不同的doAction()方法。

顺便说一句,这是我第一次遇到匿名课程。我认为我理解这个概念,但实际使用它们是另一个故事。

5 个答案:

答案 0 :(得分:7)

您正在使用public void doAction(Word w1, Word w2),但您在父级中有public void doAction()。因此不会覆盖父方法。

答案 1 :(得分:6)

您实际 重载方法doAction()。但我怀疑你可能会混淆重载覆盖这两个词。

要使方法重载,请使用不同数量或类型的参数。这允许相同的方法根据您调用它的如何(即使用什么参数)执行不同的操作。

Information on overloading

要覆盖方法,请使用相同数量和类型的参数,并且需要返回与重写(super)方法相同的类型。这允许相同的方法根据您调用它的 where (即从超类或子类)执行不同的操作。

Information on overriding

答案 2 :(得分:6)

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

代码是关于如何维护Action类的不同匿名版本列表的简单演示。它有效。

您遇到的问题是您实际上没有覆盖doAction()方法。相反,你重载了它。

  

当我尝试从中访问覆盖的doAction()方法时   allActions列表,它只是执行默认方法。

这是因为匿名类的所有对象都使用了从Action类继承的doAction()方法而不是您错误地认为已覆盖原始方法的doAction(Word w1, Word w2)方法。

提示:当您覆盖某些方法时,请确保方法签名保持一致。一个例外是重写方法可能具有重写方法的子类型的返回类型。

答案 3 :(得分:3)

您需要了解重写方法和重载方法之间的区别。在重载时,您可以使用相同的方法名称,但不同的参数列表和返回值,如果您愿意,可以将它们全部放在同一个类中。在重写时,您拥有的子类具有完全相同的方法名称,而不是基类中的方法。

您可能正在寻找的是所有实现相同界面的类列表。例如,使用名为Action的接口,该接口包含不带参数的方法和名为execute()的void返回类型。然后创建每个类并让它实现此接口。在调用方法之前,使用构造函数或getter和setter设置对象的内部状态。 execute方法只会针对您已经提供的状态触发您想要发生的活动。然后将这些Action对象添加到接口类型列表中。

现在,您只需遍历列表,为从列表中检索的每个Action引用调用execute()方法。

答案 4 :(得分:1)

  

但是这段代码对我不起作用。当我尝试从allActions列表中访问覆盖的doAction()方法时,它只执行默认方法。

实际上,您还没有覆盖该方法。你已经重载了...而调用该方法的代码显然使用的是旧方法签名。

只有将签名保留为您要覆盖的方法时才会覆盖; e.g。

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

(问题不在于您对匿名类的理解。您了解覆盖和重载之间的差异......以及理解您应该在此上下文中使用哪些内容。)