开发者

Java noob needs clarification on wierd overloaded method issue

In my real code I have an object pool that creates "Foo"'s which I totally forgot about. The problem is that I am never creating "Bar"s in the firstplace! I didn't realize it until some of you mentioned my error in the example with doing "IExample Bar". Thank you.

I am relatively new to Java and I am trying to understand why this won't work. Consider the following (very crude) example:

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

So it looks like only the parent class' version of myOverriddenMethod() is ever called. Bar's version never does. I tried to find information on why this happens, but had little luck.

Can an开发者_开发知识库yone explain this phenomena? Also, suggested workarounds/design changes are welcome. Thanks.


I'm pretty sure the problem is in "assume this gets called in a listener fashion". Right now, there's nothing in there that's going to cause SomeClass.myMethod() to get called, so there's nothing that's going to cause myOverridenMethod() to get called. The modified (if ugly) version below works fine; maybe you should post your actual code?

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


EDIT - First of all @Peter Lawrey comment is correct, you do not have myMethod() but I am assuming you meant Bar bar = new Bar(); instead for my answer.

Because you are invoking the parent class myMethod().

Bar is a child class of parent Foo. So when you invoke bar.myMethod();, you are actually invoking Foo's myMethod(). In the parent class you set myVar to be "Foo" (by calling myOverriddenMethod();), so that's what it gets set to.

If you want the value to be Bar, then you will need to override myMethod() in your child class Bar.

The code you provided has number of issues, so I re-created a simple scenario for you so that you can understand the concepts:-

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
        }

}

Hope this helps!


The code does not compile. If one modify it a bit so that it compile (and it is really hard to guess how the code should looks like), then the myVar is set to Bar like expected.

The code how I interpret it:

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";
    }
}

prove:

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

The code works like expected. If you really "run" the code is:

  • different than mine
  • or more likely your IDE run an older compilable version, but not the one you posted.
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜