"Is it a good practice in Java to override a non-abstract method?" Yes.
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();
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With