Definición 1: Si para cada objeto O1 del tipo T1 hay un objeto O2 del tipo T2, de modo que todos los programas P definidos en T1 no tienen cambios en el comportamiento cuando todos los objetos O1 se reemplazan con O2, entonces el tipo T2 es un subtipo de tipo T1.
Definición 2: Todos los lugares que se refieren a las clases base deben poder usar objetos de sus subclases de manera transparente.
El origen del problema: hay una función P1, que se completa con la clase A. Ahora es necesario expandir la función P1, y la función extendida es P, donde P consiste en la función original P1 y la nueva función P2. La nueva función P se completa mediante la subclase B de la clase A. La subclase B puede hacer que la función original P1 falle al completar la nueva función P2.
Solución: cuando use la herencia, siga el principio del reemplazo de Richter. Cuando la Clase B hereda la Clase A, además de agregar nuevos métodos para completar la nueva función P2, trate de no reescribir los métodos de la Clase A de los padres, e intente no sobrecargar los métodos de la clase principal A.
La herencia contiene el significado de: cualquier método que se haya implementado en la clase principal (en relación con los métodos abstractos) en realidad está estableciendo una serie de especificaciones y contratos. Aunque no obliga a todas las subclases a cumplir con estos contratos, si la subclase modifica arbitrariamente estos métodos no abstractos, dañará todo el sistema de herencia. El principio del reemplazo de Lizur expresa este significado.
La herencia, como una de las tres características principales orientadas a objetos, aporta una gran comodidad a la programación, pero también trae desventajas. Por ejemplo, el uso de la herencia traerá invasividad al programa, la portabilidad del programa reducirá y aumentará el acoplamiento entre objetos. Si otras clases heredan una clase, cuando esta clase debe modificarse, se deben tener en cuenta todas las subclases. Después de modificar la clase principal, todas las funciones que involucran subclases pueden fallar.
ejemplo:
Rectángulo de clase pública {int width; int altura; Rectángulo público (int w, int h) {width = w; altura = h; } public int getArea () {Ancho de retorno*altura; }} public class Square extiende rectángulo {public Square (int w, int h) {super (w, h); } public int getArea () {Width de retorno*ancho; }} prueba de clase pública {public static void main (string [] args) {rectangle rectangle = new Rectangle (10, 20); // rectángulo cuadrado = nuevo cuadrado (10, 20); System.out.println ("área:"+rectangle.getArea ()); }}
Si reemplazamos el rectángulo de la clase rectángulo con el cuadrado de clase cuadrada, el área que encontramos es incorrecta porque reescribimos el método GetArea de la clase principal al heredar. Esto viola el principio del reemplazo de Lissian.
Por supuesto, aquí hay solo un ejemplo, no modificaremos esto en proyectos reales.
Resumir:
1. Trate de no reescribir el método de clase principal, pero agregue sus propios métodos únicos.
2. Mientras que la herencia trae una gran comodidad a la programación, también trae desventajas. Si otras clases heredan una clase, cuando esta clase debe modificarse, se deben tener en cuenta todas las subclases. Después de modificar la clase principal, todas las funciones que involucran subclases pueden tener errores.