2

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?

2
  • 1
    You can prevent subclasses from overriding methods by making those methods final in your superclass. Or make those methods private, then they are not visible in subclasses. (Methods that should be used internally in a class only should be private). Commented Mar 26, 2015 at 14:57
  • But I want them to be overriden. They should provide the same interface in the Derived class as they do in the Basic class. It's just that Derived methods should not break Basic Methods. Commented Mar 26, 2015 at 15:01

3 Answers 3

5

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.

Sign up to request clarification or add additional context in comments.

Comments

3

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");
    }
}

Comments

1

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).

3 Comments

Sometimes it happens when people override your methods in ways that were not considered. It may not be ideal, but I've had this happen a lot.
What I suggested is exactly what you too suggested in your answer: delcare one private method (not ovveridable) and another one overridable.
Fair enough, I missed that.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.