JavaNoob需要澄清wierd重载方法问题
在我的真实代码中,我有一个对象池,它创建了我完全忘记的“Foo”。问题是,我从来没有创造“酒吧”放在首位!直到你们中的一些人提到我在示例中执行“IExample Bar”时的错误,我才意识到这一点。多谢各位 我对Java比较陌生,我正在努力理解为什么这不起作用。考虑下面(非常粗糙)的例子: 所以看起来只有父类版本的MyOverridedMethod()被调用过。Bar的版本从来没有这样做过。我试图找到这一切发生的原因,但运气不佳JavaNoob需要澄清wierd重载方法问题,java,oop,Java,Oop,在我的真实代码中,我有一个对象池,它创建了我完全忘记的“Foo”。问题是,我从来没有创造“酒吧”放在首位!直到你们中的一些人提到我在示例中执行“IExample Bar”时的错误,我才意识到这一点。多谢各位 我对Java比较陌生,我正在努力理解为什么这不起作用。考虑下面(非常粗糙)的例子: 所以看起来只有父类版本的MyOverridedMethod()被调用过。Bar的版本从来没有这样做过。我试图找到这一切发生的原因,但运气不佳 有人能解释这种现象吗?此外,建议的解决方案/设计变更也受欢迎。谢谢
有人能解释这种现象吗?此外,建议的解决方案/设计变更也受欢迎。谢谢。编辑-首先@Peter Lawrey的评论是正确的,您没有
myMethod()
,但我假设您的意思是Bar=new Bar()代码>而不是我的答案
因为您正在调用父类myMethod()
Bar
是父Foo
的子类。因此,当您调用bar.myMethod()时代码>,实际上您正在调用Foo的myMethod()
。在父类中,您将myVar设置为“Foo”(通过调用myOverridedMethod();
),因此这就是它的设置
如果希望值为Bar
,则需要在子类Bar
中重写myMethod()
您提供的代码有很多问题,因此我为您重新创建了一个简单的场景,以便您能够理解这些概念:-
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
}
}
希望这有帮助 我很确定问题出在“假设它以侦听器方式被调用”。现在,没有任何东西会导致调用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);
}
}
代码不编译。如果有人稍微修改它,使它能够编译(而且很难猜测代码应该是什么样子的),那么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运行的是较旧的可编译版本,而不是您发布的版本
您的示例无法编译,也没有意义。IExample没有myMethod()
所以你不能调用它代码>应该是Bar=newbar()代码>@Ralph——你在说什么?只要SomeClass
是在别处定义的类或接口,这正是创建它的匿名内部子类的方法。@David Moles-对于给定的代码,很难理解OP为什么需要一个内部类。@Ralph如果他试图定义一个命名的内部类,你当然是正确的。我为“你在说什么”道歉。很好的观察。。。你认为他是在暗示swing事件的监听者吗?@CoolBeans——我不知道。:)但是我看不到myMethod()真正调用someMethod()的任何其他方式……是的。。。我认为OP拷贝粘贴了随机的代码片段。我猜他是在问继承的问题。@CoolBeans是的,那里可能有继承问题,但我们还没有看到。但是这段代码没有重现“现象”child。someVar
将变成child
@Ralph这不是OP想要的吗?起初我以为我理解了这个问题,但在浏览了我们之间的所有评论之后,我对现在的实际问题感到困惑。也许我应该删除我的答案。不,不要删除你的答案,这对你解释问题的方式很好。但是请您指出,它并没有回答这个问题,而是显示了如何“修改”代码以获得预期的结果。
@Test
public void test() {
Bar bar = new Bar();
bar.myMethod();
assertEquals("Bar", bar.myVar);
}