¿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 seansealedofinal, las subclases pueden ser extendidas por otras clases.En Scala, esto se usa para modelar tipos de datos algebraicos cerrados, por lo que el
Listtipo canónico de Haskell :se puede modelar en Scala así:
Y puede garantizar que solo existen esas dos subclases porque
Listessealedy, por lo tanto, no puede extenderse fuera del archivo,Consesfinaly, por lo tanto, no puede extenderse en absoluto yNiles unaobjectque 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
Listtipo que si hace una discriminación de casoNilyCons, no habrá ninguna otra alternativa apareciendo a sus espaldas.fuente
abstract internalmiembro.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
Nodeclase que implementa un patrón de visitante para manejar todos los tipos de nodos.fuente
Nodeclase base , por supuesto, no contiene ninguna referencia directa a sus subclases. Pero contiene unacceptmétodo con unVisitorparámetro. YVisitorcontiene unvisitmétodo por cada subclase. Entonces, a pesar deNodeno tener referencias directas a sus subclases, "las conoce" indirectamente, a través de laVisitorinterfaz. 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