【发布时间】:2010-04-24 21:36:24
【问题描述】:
如果我有一个父子定义一些方法 .foo() 像这样:
class Parent {
public void foo(Parent arg) {
System.out.println("foo in Function");
}
}
class Child extends Parent {
public void foo(Child arg) {
System.out.println("foo in ChildFunction");
}
}
当我这样称呼他们时:
Child f = new Child();
Parent g = f;
f.foo(new Parent());
f.foo(new Child());
g.foo(new Parent());
g.foo(new Child());
输出是:
foo in Parent
foo in Child
foo in Parent
foo in Parent
但是,我想要这个输出:
foo in Parent
foo in Child
foo in Parent
foo in Child
我有一个扩展父类的子类。在 Child 类中,我想“部分覆盖”Parent 的foo(),也就是说,如果参数arg 的类型是 Child,则调用 Child 的 foo() 而不是 Parent 的 foo()。
当我小时候打电话给f.foo(...) 时,这行得通;但是如果我从它的父别名中引用它,例如g.foo(...),那么无论arg 的类型如何,都会调用父级的foo(..)。
据我了解,我所期望的不会发生,因为 Java 中的方法重载是早期绑定(即在编译时静态解析),而方法覆盖是后期绑定(即在编译时动态解析),因为我用技术上不同的参数类型定义了一个函数,我在技术上用不同的定义重载了父类的定义,而不是覆盖它。但是,当 .foo() 的参数是父级 foo() 的参数的子类时,我想做的是在概念上“部分覆盖”。
我知道我可以在 Child 中定义一个桶覆盖 foo(Parent arg) 来检查 arg 的实际类型是 Parent 还是 Child 并正确传递它,但是如果我有 20 个 Child,那将是大量重复类型不安全的代码。
在我的实际代码中,Parent 是一个名为“Function”的抽象类,它简单地抛出 NotImplementedException()。子项包括“多项式”、“对数”等,.foo() 包括 Child.add(Child)、Child.intersectionsWith(Child) 等。并非所有 Child.foo(OtherChild) 的组合都是可解的并且在事实上,甚至不是所有 Child.foo(Child) 都是可解决的。所以我最好先定义所有未定义的东西(即抛出 NotImplementedException),然后只定义那些可以定义的东西。
所以问题是:有没有办法只覆盖父级的 foo() 的一部分?还是有更好的方法来做我想做的事?
编辑:
@Zeiss:如果我使用 Double Dispatch,像这样:
class Parent {
public void foo(Parent arg) {
System.out.println("foo in Parent");
}
}
class Child extends Parent {
public void foo(Parent arg) {
System.out.println("foo in Child(Parent)");
arg.foo(this);
}
public void foo(Child arg) {
System.out.println("foo in Child(Child)");
}
}
我得到了无限递归:
(stack):
StackOverflowError: ...
...
at sketch_apr25a$Child.foo(sketch_apr25a.java:35)
...
(output):
...
foo in Child(Parent)
...
在执行g.foo(new Child()); 时。其余的似乎都很好,因为输出是:
foo in Child(Parent)
foo in Parent
foo in Child(Child)
foo in Child(Parent)
foo in Parent
foo in Child(Parent)
(infinite recursion follows)
为什么会这样? g 是 Parent 的别名,但它正在访问 Child 的 foo(Parent)?
【问题讨论】:
标签: java dynamic overloading overriding