Reputation: 1179
I have a Base class method, that I want to override in a Derived class.
The derived class method should be called whenever the method with the same name is accessed from "outside" or from the derived class. When acessing the method from inside the base class, I want the base class method to be used. Consider the following code:
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
}
}
I want the following output:
Doing something old
-------------------------------
Doing something completely new
But it produces this output:
Doing something completely new
-------------------------------
Doing something completely new
I thought that explicitly stating the base class name in Basic.this.doSomething();
should do that trick, but apparently it does not.
Obviously, I could declare a variable of type Basic inside a Derived class instead of Deriving, but that kind of defeats the idea that the Derived class "is-a" Basic class and would force me to write oneline-redirection methods to obtain the same interface.
Here is why I want to do that:
When writing base classes, I want to use methods where I have the guarantee that inside the base class, the methods that I wrote are used, because I do not want deriving classes to interfere with base class internals. To me, it makes sense from an encapsulation standpoint, but maybe I am wrong?
The Basic#doSomething()
method can be called from the Basic()
constructor.
If the Derived#doSomething()
method uses ressources from Derived
, then those ressources will only be available after Derived
construction.
However: Derived
construction finishes AFTER the superclass construction, which means that when Derived
is constructed, the Derived#doSomething()
is called in the Basic()
constructor and it will access uninitialized data.
Is there a way around this?
Upvotes: 2
Views: 238
Reputation: 543
What you want to do is bad, from a design point of view. A good design would be to declare two separate methods, one overridable and the other not (either final or private).
Upvotes: 1
Reputation: 9786
Make an inner method in Basic for doSomething and call that directly:
static class Basic {
public Basic()
{
doSomethingImpl();
}
public void doSomething()
{
doSomethingImpl();
}
private void doSomethingImpl()
{
System.out.println("Doing something old");
}
}
Upvotes: 3
Reputation: 6279
Calling veritable methods from a constructor is a bad practice, more could be found here: On invoking overridable method from constructors
As for enforcing to call the base class method - it's impossible.
Upvotes: 5