Java noob需要澄清wierd重载方法问题

时间:2011-10-07 17:40:19

标签: java oop

在我的真实代码中,我有一个创建“Foo”的对象池,我完全忘了。问题是我从来没有在第一时间创建“Bar”!直到你们中的一些人在做“IExample Bar”的例子中提到了我的错误,我才意识到这一点。谢谢。

我对Java比较陌生,我试图理解为什么这不起作用。考虑以下(非常粗略)的例子:

interface IExample {
    public void myOverriddenMethod();
    public void myMethod();
}

class Foo implements IExample {
    protected string myVar;

    public void myMethod() {
        SomeClass anotherclass = new SomeClass() {
            // assume this gets called in a listener fashion
            public void someMethod() {
                myOverriddenMethod();
            }
        }
    }

    public void myOverriddenMethod(){
        myVar = "Foo";
    }
}

class Bar extends Foo implements IExample {
    public void myOverriddenMethod(){
        myVar = "Bar";
    }
}



IExample bar = new Bar();
bar.myMethod();     // expect myVar to be equal to to "Bar", but it is equal to "Foo". 

因此看起来只调用myOverriddenMethod()的父类'版本。 Bar的版本永远不会。我试图找到有关为什么会发生这种情况的信息,但运气不佳。

任何人都可以解释这种现象吗?此外,欢迎建议的变通方法/设计变更。感谢。

3 个答案:

答案 0 :(得分:1)

编辑 - 首先@Peter Lawrey评论是正确的,你没有myMethod(),但我假设你的意思是Bar bar = new Bar();而不是我的答案。

因为您正在调用父类myMethod()

Bar是父Foo的子类。因此,当您调用bar.myMethod();时,实际上是在调用Foo的myMethod()。在父类中,您将myVar设置为“Foo”(通过调用myOverriddenMethod();),这就是它设置的内容。

如果您希望值为Bar,那么您需要在子类myMethod()覆盖 Bar

您提供的代码有很多问题,所以我为您重新创建了一个简单的场景,以便您可以理解这些概念: -

public interface SomeInterface {
    void test();
}

public class ParentClazz implements SomeInterface{
    protected String someVar;
    public void test() {
        this.someVar="parent";
    }
    public void someMethod(){
        System.out.print("Parent Called!");
        test();
        System.out.print(someVar);
    }
}

public class ChildClazz extends ParentClazz implements SomeInterface {
    public void test() {
        this.someVar="child";
    }
    @Override
    public void someMethod(){
        System.out.print("Child Called!");
        test();
        System.out.print(someVar);
    }
}

public class StackOverFlow {

    public static void main(String[] args) {
        ChildClazz child = new ChildClazz();
        child.someMethod(); //prints child
        }

}

希望这有帮助!

答案 1 :(得分:1)

我很确定问题在于“假设以侦听器方式调用”。现在,没有任何内容会导致SomeClass.myMethod()被调用,所以没有任何东西可以导致myOverridenMethod()被调用。下面修改过的(如果丑陋)版本工作正常;也许你应该发布你的实际代码?

interface IExample {
    void myMethod();
    void myOverriddenMethod();
}

interface SomeListener extends EventListener {
    void someMethod();
}

class Foo implements IExample
{
    private EventListenerList ll = new EventListenerList();

    protected String myVar;

    protected Foo() {
        ll.add(SomeListener.class, new SomeListener()
        {
            @Override
            public void someMethod()
            {
                myOverriddenMethod();
            }
        });
    }

    public void myMethod() {
        for( SomeListener l : ll.getListeners(SomeListener.class) )
        {
            l.someMethod();
        }
    }

    @Override
    public void myOverriddenMethod()
    {
        myVar = "Foo";
    }
}

class Bar extends Foo {
    @Override
    public void myOverriddenMethod()
    {
        myVar = "Bar";
    }

    public static void main(String[] args) {
        IExample bar = new Bar();
        bar.myMethod();
        System.out.println(((Bar) bar).myVar);
    }
}

答案 2 :(得分:1)

代码无法编译。如果有人修改它以便编译(并且很难猜出代码应该是什么样子),那么myVar就像预期的那样设置为Bar

我如何解释它的代码:

public interface IExample {
    public void myOverriddenMethod();
}

interface SomeClass {
    public void someMethod();
}

class Foo implements IExample {
    protected String myVar;


    public void myMethod() {
        SomeClass anotherclass = new SomeClass(){
            @Override
            public void someMethod() {
                myOverriddenMethod();

            }
        };
        anotherclass.someMethod();
    }

    public void myOverriddenMethod() {
        myVar = "Foo";
    }
}

class Bar extends Foo implements IExample {
    public void myOverriddenMethod(){
        myVar = "Bar";
    }
}

证明:

@Test
public void test() {
    Bar bar = new Bar();
    bar.myMethod();
    assertEquals("Bar", bar.myVar);
}

代码的工作方式与预期的一样。如果你真的“运行”代码是:

  • 与我的不同
  • 或者更可能您的IDE运行较旧的可编译版本,但不是您发布的版本