Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to make a method which is not abstract but must be overridden?

People also ask

Can non-abstract method be overridden?

"Is it a good practice in Java to override a non-abstract method?" Yes.

Is it mandatory to override abstract method?

A subclass must override all abstract methods of an abstract class. However, if the subclass is declared abstract, it's not mandatory to override abstract methods.


There is no direct compiler-enforced way to do this, as far as I know.

You could work around it by not making the parent class instantiable, but instead providing a factory method that creates an instance of some (possible private) subclass that has the default implementation:

public abstract class Base {
  public static Base create() {
    return new DefaultBase();
  }

  public abstract void frobnicate();

  static class DefaultBase extends Base {
    public void frobnicate() {
      // default frobnication implementation
    }
  }
}

You can't write new Base() now, but you can do Base.create() to get the default implementation.


As others have pointed out, you can't do this directly.

But one way to do this is to use the Strategy pattern, like so:

public class Base {
    private final Strategy impl;

    // Public factory method uses DefaultStrategy
    // You could also use a public constructor here, but then subclasses would
    // be able to use that public constructor instead of the protected one
    public static Base newInstance() {
        return new Base(new DefaultStrategy());
    }

    // Subclasses must provide a Strategy implementation
    protected Base(Strategy impl) {
        this.impl = impl;
    }

    // Method is final: subclasses can "override" by providing a different
    // implementation of the Strategy interface
    public final void foo() {
        impl.foo();
    }

    // A subclass must provide an object that implements this interface
    public interface Strategy {
        void foo();
    }

    // This implementation is private, so subclasses cannot access it
    // It could also be made protected if you prefer
    private static DefaultStrategy implements Strategy {
        @Override
        public void foo() {
            // Default foo() implementation goes here
        }
    }
}

Consider making an interface with this method. Class descendants will have to implement it.


I think the easiest way is to create an abstract class that inherits from the base class:


public class Base {
    public void foo() {
        // original method
    }
}

abstract class BaseToInheritFrom extends Base {
    @Override
    public abstract void foo();
}

class RealBaseImpl extends BaseToInheritFrom {
    @Override
    public void foo() {
        // real impl
    }
}

No, that's the whole point of an abstract method. What is your use case? Perhaps we can think about it based on the underlying need.


How about this: inside the default implementation of the method, use reflection to get the exact Class of the object. If the Class does not match your base class exactly, throw a RuntimeException or equivalent.

public class Parent {

    public void defaultImpl(){
        if(this.getClass() != Parent.class){
            throw new RuntimeException();
        }
    }

}