fat-lobyte
fat-lobyte

Reputation: 1179

Java: Force base class to use base class method instead of overriden method

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

Answers (3)

Giovanni
Giovanni

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

Necreaux
Necreaux

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

Petr
Petr

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

Related Questions