No, it is not a code smell.
- If a class is not final, it allows to be subclassed.
- If a method is not final, it allows to be overridden.
It lies within the responsabilities of each class to carefully consider if subclassing is appropriate, and which methods may be overridden.
The class may define itself or any method as final, or may place restrictions (visibility modifiers, available constructors) on how and where it is subclassed.
The usual case for overriding methods is a default implementation in the base class which may be customized or optimized in the subclass (especially in Java 8 with the advent of default methods in interfaces).
class A {
public String getDescription(Element e) {
// return default description for element
}
}
class B extends A {
public String getDescription(Element e) {
// return customized description for element
}
}
An alternative for overriding behaviour is the Strategy Pattern, where the behaviour is abstracted as an interface, and the implementation can be set in the class.
interface DescriptionProvider {
String getDescription(Element e);
}
class A {
private DescriptionProvider provider=new DefaultDescriptionProvider();
public final String getDescription(Element e) {
return provider.getDescription(e);
}
public final void setDescriptionProvider(@NotNull DescriptionProvider provider) {
this.provider=provider;
}
}
class B extends A {
public B() {
setDescriptionProvider(new CustomDescriptionProvider());
}
}
virtual
keyword to support overrides. So, the issue is made more (or less) ambiguous by the particulars of the language.final
modifier exists exactly for situations like these. If the behavior of the method is such that it is not designed to be overridden, then mark it asfinal
. Otherwise, expect that developers may choose to override it.