Search code examples
javainheritancesuperclasssubclassingoverriding

How to call the superclass implementation of an overridden method from inside the superclass in Java?


Suppose I have two classes SuperClass and SubClass which extends SuperClass, such as below:

public abstract class SuperClass {
    private Object field1;

    protected SuperClass(Object obj) {
        setField1(obj);
    }

    public void setField1(Object obj) {
        // perform some check on obj and
        // then set field1 such that field1==obj
    }
}


public class SubClass extends SuperClass {
    public SubClass(Object obj) {
        super(obj);
    }

    @Override
    public void setField1(Object obj) {
        super.setField1(obj);
        // do some work that is necessary only when
        // field1 is set through SubClass.setField1()
    }
}

What I need is, when I create an object of SubClass, I need method SuperClass.setField1() to be called from inside SuperClass constructor, not SubClass.setField1(). But with the above code, method SubClass.setField1() is called which causes a NullPointerException to be thrown, since the work done in SubClass.setField1() is performed on a field that's yet null.

Is there any way to explicitly call SuperClass.setField1()‍‍‍ from inside SuperClass constructor?


Solution

  • You could move said method body to a private method and let the default method (the one which may be overridden by the subclass) delegate to the former. See this example

    public abstract class SuperClass {
    
        private Object field1;
    
        protected SuperClass(Object obj){
            // call the safe implementation
            setField1Safe(obj);
        }
    
    
        public void setField1(Object obj){
            // just delegates
            setField1Safe(obj);
        }
    
        private void setField1Safe(Object obj){
            // perform some check on obj and
            // then set field1 such that field1==obj
        }
    }
    
    public class SubClass extends SuperClass{
         public SubClass(Object obj){
             super(obj);
         }
    
         @Override
         public void setField1(Object obj){
             super.setField1(obj);
             // do some work that is necessary only when
             // field1 is set through SubClass.setField1()
         }
    }
    

    That way the sub class can still override setField1 but if you really depend on the implementation then you can call the private setField1Safe method.