Yo diría, asumiendo el riesgo de ser derribado, que la herencia es un olor de código en sí mismo :)
El problema con la herencia es que se puede usar para dos propósitos ortogonales:
- interfaz (para polimorfismo)
- implementación (para reutilización de código)
En primer lugar, tener un solo mecanismo para obtener ambos es lo que lleva al "abuso de la herencia", ya que la mayoría de la gente espera que la herencia se trate de la interfaz, pero se puede usar para obtener la implementación predeterminada incluso por programadores cuidadosos. tan fácil de pasar por alto esto ...)
De hecho, los idiomas modernos como Haskell o Go, han abandonado la herencia para separar ambas preocupaciones.
Volver a la pista:
Una violación del Principio de Liskov es, por lo tanto, la señal más segura, ya que significa que la parte de "interfaz" del contrato no se respeta.
Sin embargo, incluso cuando se respeta la interfaz, es posible que tenga objetos que se heredan de clases básicas "completas" simplemente porque uno de los métodos se consideró útil.
Por lo tanto, el Principio de Liskov en sí mismo no es suficiente, lo que necesita saber es si el polimorfismo es utilizado o no. Si no lo es, entonces no tenía mucho sentido heredar, eso es un abuso.
Resumen:
- forzar el
Liskov Principle
- compruebe que realmente se usa
Una forma de evitarlo:
Imponiendo una clara separación de preocupaciones:
- solo se hereda de las interfaces
- utilizar la composición para delegar la implementación
significa que se necesitan al menos un par de pulsaciones de tecla para cada método y, de repente, las personas comienzan a pensar si es o no tan buena idea reutilizar esta clase "gorda" solo por una pequeña parte.