2

我有一个类 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() 方法。

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

4

5 回答 5

7

你正在使用public void doAction(Word w1, Word w2),但你有public void doAction()父母。所以父方法不会被覆盖。

于 2012-12-07T05:17:46.560 回答
6

您实际上正在重载方法doAction()。但我怀疑您可能混淆了超载覆盖这两个词。

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

超载信息

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

覆盖信息

于 2012-12-07T05:25:41.347 回答
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()方法。相反,您重载了它。

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

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

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

于 2012-12-07T05:50:07.570 回答
3

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

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

现在您所要做的就是遍历列表,为您从列表中检索到的每个 Action 引用调用 execute() 方法。

于 2012-12-07T05:36:11.273 回答
1

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

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

仅当您将签名保留为您尝试覆盖的方法时才会发生覆盖;例如

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

(问题不在于您对匿名类的理解。而在于您对覆盖和重载之间的区别的理解......以及在这种情况下应该使用的理解。)

于 2012-12-07T06:15:31.240 回答