¿Debería una clase saber sobre sus subclases? ¿Debería una clase hacer algo específico para una subclase dada, por ejemplo?
Mis instintos me dicen que es un mal diseño, parece un antipatrón de algún tipo.
¿Debería una clase saber sobre sus subclases? ¿Debería una clase hacer algo específico para una subclase dada, por ejemplo?
Mis instintos me dicen que es un mal diseño, parece un antipatrón de algún tipo.
Respuestas:
La respuesta que implica el concepto de clases es "no".
Cualquiera que sea la acción, los datos o la relación que esté manejando es parte de todas las subclases, entonces debe manejarse en la superclase sin verificar el tipo real. O se aplica solo a algunas subclases: entonces tendría que realizar verificaciones de tipo en tiempo de ejecución para hacer lo correcto, la superclase tendría que cambiarse cada vez que alguien más herede de ella (o podría hacer silenciosamente lo incorrecto), los cambios en las clases derivadas pueden romper la superclase sin cambios, etc.
En resumen, obtienes una serie de malas consecuencias que generalmente son lo suficientemente malas como para rechazar tales soluciones de inmediato. Si varias de sus subclases hacen lo mismo y desea evitar la duplicación de código (prácticamente siempre es algo bueno), una mejor solución es introducir una clase de nivel medio de la que todas esas subclases puedan heredar el código.
fuente
¡No solo no debería saberlo, simplemente no puede ! Por lo general, una clase se puede extender en cualquier momento y en cualquier lugar. Puede ser extendido por clases que ni siquiera existían cuando fue escrito.
Algunos lenguajes permiten que las clases extendidas sean controladas por la superclase. En Scala, una clase puede marcarse como
sealed
, lo que significa que solo puede ser extendida por otras clases dentro de la misma unidad de compilación (archivo fuente). Sin embargo, a menos que esas subclases también seansealed
ofinal
, las subclases pueden ser extendidas por otras clases.En Scala, esto se usa para modelar tipos de datos algebraicos cerrados, por lo que el
List
tipo canónico de Haskell :se puede modelar en Scala así:
Y puede garantizar que solo existen esas dos subclases porque
List
essealed
y, por lo tanto, no puede extenderse fuera del archivo,Cons
esfinal
y, por lo tanto, no puede extenderse en absoluto yNil
es unaobject
que no puede extenderse de todos modos.Pero este es un caso de uso específico (modelado de tipos de datos algebraicos a través de la herencia) e incluso en este caso, la superclase en realidad no conoce sus subclases. Es más una garantía para el usuario del
List
tipo que si hace una discriminación de casoNil
yCons
, no habrá ninguna otra alternativa apareciendo a sus espaldas.fuente
abstract internal
miembro.La respuesta simple es no.
Hace que el código sea frágil y da a conocer dos principios básicos de la programación orientada a objetos.
fuente
Sí a veces. Por ejemplo, cuando existe un número limitado de subclases. Un patrón de visitante es una ilustración de la utilidad de este enfoque.
Ejemplo: todos los nodos de árbol de sintaxis abstracta (AST) de una gramática bien definida pueden heredarse de una sola
Node
clase que implementa un patrón de visitante para manejar todos los tipos de nodos.fuente
Node
clase base , por supuesto, no contiene ninguna referencia directa a sus subclases. Pero contiene unaccept
método con unVisitor
parámetro. YVisitor
contiene unvisit
método por cada subclase. Entonces, a pesar deNode
no tener referencias directas a sus subclases, "las conoce" indirectamente, a través de laVisitor
interfaz. Todos se unieron a través de él.Si escribo un componente para una empresa y luego, después de que me vaya, alguien lo extiende para sus propios fines, ¿debo informarme al respecto?
¡No!
Lo mismo con las clases. Confía en tus instintos.
fuente