É verdade que substituir métodos concretos é um cheiro de código? Porque eu acho que se você precisar substituir métodos concretos:
public class A{
public void a(){
}
}
public class B extends A{
@Override
public void a(){
}
}
pode ser reescrito como
public interface A{
public void a();
}
public class ConcreteA implements A{
public void a();
}
public class B implements A{
public void a(){
}
}
e se B quiser reutilizar um () em A, ele pode ser reescrito como:
public class B implements A{
public ConcreteA concreteA;
public void a(){
concreteA.a();
}
}
que não requer herança para substituir o método, isso é verdade?
virtual
palavra-chave para dar suporte a substituições. Portanto, a questão é tornada mais (ou menos) ambígua pelos detalhes da linguagem.
final
modificador existe exatamente para situações como estas. Se o comportamento do método não for projetado para ser substituído, marque-o como final
. Caso contrário, espere que os desenvolvedores optem por substituí-lo.