在我的真实代码中,我有一个创建“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的版本永远不会。我试图找到有关为什么会发生这种情况的信息,但运气不佳。
任何人都可以解释这种现象吗?此外,欢迎建议的变通方法/设计变更。感谢。
答案 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);
}
代码的工作方式与预期的一样。如果你真的“运行”代码是: