如果我有一个父子关系,它定义了如下的method.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
我有一个扩展父类的子类。在子类中,我希望“部分重写”父类的
foo()
,也就是说,如果
arg
的类型是child,然后是child
英尺()
被调用而不是父的
英尺()
.
我打电话的时候没问题
f.foo(...)
作为一个孩子;但是如果我从它的父别名中引用它,比如
g.foo(...)
那么父母的
foo(..)
不分类型地调用
精氨酸
.
据我所知,我所预期的不会发生,因为Java中的方法重载是早期绑定(即在编译时静态解析),而方法重写是后期绑定(即在编译时动态解析),并且因为我定义了一个具有不同技术的函数。ent type,我在技术上用一个不同的定义重载父类定义,而不是重写它。但我想做的是在概念上“部分覆盖”什么时候。
英尺()
的参数是
英尺()
的论点。
我知道我可以定义bucket override
foo(Parent arg)
在检查arg的实际类型是父类型还是子类型并正确传递它的child中,但是如果我有20个子类型,那将是类型不安全代码的大量重复。
在我的实际代码中,parent是一个名为“function”的抽象类,它只是抛出
NotImplementedException()
. 子项包括“多项式”、“对数”等,foo()包括child.add(child)、child.intersectionswith(child)等。不是child.foo(otherchild)的所有组合都是可解的,事实上甚至不是所有child.foo(child)都是可解的。所以我最好还是定义所有未定义的东西(即抛出notimplementedexception),然后只定义那些可以定义的东西。
所以问题是:有什么方法可以只覆盖父对象的foo()部分吗?还是有更好的方法做我想做的事?
编辑
:
@蔡司:如果我使用双重调度,就像这样:
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是父代的别名,但它正在访问子代的foo(父代)?