Existe una clase LinkedList con funciones como add_first (), add_last (), add_after (), remove_first (), remove_last () y remove ()
Ahora hay una pila de clases que proporciona funcionalidades como push (), pop (), peek () o top (), y para implementar estos métodos, extiende los métodos de la clase LinkedList. ¿Es esto una violación del Principio de sustitución de Liskov?
Por ejemplo, considere el caso add_after () para agregar un nodo en la enésima posición de una Lista vinculada. Esto se puede hacer en la clase base pero no en la clase Stack. ¿Se están debilitando las condiciones posteriores aquí o modifica el método add_after () para agregar a la parte superior de la Pila?
Además, si no es una violación, ¿es este un mal diseño? ¿Y cómo implementaría la funcionalidad Stack usando la clase LinkedList?
LinkedList
? Es posible que desee prestar atención a los consejos de cierto Joshua Bloch (que jugó un papel importante en el diseño del marco de colecciones de Java) cuando dijo "Prefiera la composición sobre la herencia" - ¿Quizás tenga unaLinkedList
clase dentro de su pila, pero en realidad no la extienda?LinkedList
que hace el trabajo pesado detrás de escena (composición). De esa forma, los usuarios de su código no pueden usar accidentalmente una Pila donde necesitaban una Lista o viceversa.Respuestas:
No. Está perfectamente bien agregar métodos en un subtipo.
Esto es una violación del LSP. El LSP dice que las instancias de un subtipo deben ser sustituibles por instancias de un supertipo sin cambiar las propiedades deseables de un programa. Si un subtipo elimina un método, cualquier código que llame a ese método se bloqueará (u obtendrá una
NoMethodError
excepción, o algo por el estilo). Claramente, "no estrellarse" es una propiedad deseable.Modificar el
add_after()
método de esta manera es una violación de la Regla de Historia (¡la más importante de las reglas!) Y, por lo tanto, no ayuda a corregir la violación del LSP.Mediante el uso de la composición.
NOTA: ¡Todo lo que escribí arriba solo se aplica a los idiomas que confunden los subtipos y las subclases! El LSP se trata de subtipar , no de subclasificar. En un lenguaje que no confunda los dos, sería perfectamente aceptable hacer
Stack
una subclase deLinkedList
, siempre que no lo conviertas en un subtipo deLinkedList
.fuente
Como todo ya fue abordado por Jörg W Mittag, acabo de explicar un poco la siguiente parte:
Básicamente, cuando hay una pregunta sobre si alguna jerarquía viola el LSP, depende del contrato que usted presente. Entonces, ¿qué contrato
add_after
tiene? Si suena, por loco que sea, como "Agregar un nodo en la enésima posición o en la parte superior", entonces está bien, se cumple la condición posterior, no se viola el LSP. De lo contrario, es una violación de LSP.fuente