我有一个Base类方法,我想在Derived类中重写。
只要从“外部”或派生类访问具有相同名称的方法,就应调用派生类方法。当从基类内部访问该方法时,我希望使用基类方法。请考虑以下代码:
public class TestBaseMethod
{
static class Basic {
public Basic()
{
Basic.this.doSomething(); // <<---- This should call Basic version
}
public void doSomething()
{
System.out.println("Doing something old");
}
}
static class Derived extends Basic {
Object ressource = new Object();
@Override
public void doSomething()
{
System.out.println("Doing something completely new");
// ressource.toString(); // <<---- explosion
}
}
public static void main(String[] args)
{
Basic d = new Derived();
System.out.println("-------------------------------");
d.doSomething(); // <<---- This should call Derived version
}
}
我想要以下输出:
Doing something old
-------------------------------
Doing something completely new
但它产生了这个输出:
Doing something completely new
-------------------------------
Doing something completely new
我认为明确说明Basic.this.doSomething();
中的基类名称应该这样做,但显然不会。
显然,我可以在Derived类中声明一个Basic类型的变量而不是Deriving,但是这种类型会让Derived类“is-a”Basic类失败,并迫使我编写oneline-redirection方法获得相同的界面。
这就是我想要这样做的原因:
在编写基类时,我想使用的方法是我保证在基类中使用我编写的方法,因为我不希望派生类干扰基类内部。对我来说,从封装的角度来看,它是有道理的,但也许我错了?
可以从Basic#doSomething()
构造函数调用Basic()
方法。
如果Derived#doSomething()
方法使用来自Derived
的资源,那么这些资源只有在Derived
构建后才可用。
但是:Derived
构造在超类构造之后完成,这意味着在构造Derived
时,Derived#doSomething()
在Basic()
构造函数中被调用,它将访问未初始化的数据。 / p>
有解决方法吗?
答案 0 :(得分:5)
从构造函数中调用真正的方法是一种不好的做法,更多信息可以在这里找到:On invoking overridable method from constructors
至于强制调用基类方法 - 这是不可能的。
答案 1 :(得分:3)
在Basic for doSomething中创建一个内部方法并直接调用它:
static class Basic {
public Basic()
{
doSomethingImpl();
}
public void doSomething()
{
doSomethingImpl();
}
private void doSomethingImpl()
{
System.out.println("Doing something old");
}
}
答案 2 :(得分:1)
从设计的角度来看,你想做的事情很糟糕。一个好的设计是声明两个单独的方法,一个是可覆盖的,另一个不是(最终的或私有的)。