El principio de reemplazo de Rich, OCP, como el principio de alto nivel de OO, aboga por el uso de "abstracción" y "polimorfismo" para cambiar la estructura estática en el diseño en una estructura dinámica para mantener el recinto del diseño. "Abstract" es una función proporcionada por el idioma. El "polimorfismo" es implementado por semántica heredada.
El principio de reemplazo de Richter contiene los siguientes 4 significados:
Ahora podemos explicar los cuatro significados anteriores.
Las subclases pueden implementar métodos abstractos de la clase principal, pero no pueden anular los métodos no abstractos de la clase principal.
Cuando estamos diseñando sistemas, a menudo diseñamos interfaces o clases abstractas, y luego los subclases implementan métodos abstractos. El principio de reemplazo de Richter en realidad se usa aquí. Es fácil entender que las subclases pueden implementar el método abstracto de la clase principal. De hecho, las subclases deben implementar completamente el método abstracto de la clase principal, incluso si escriben un método vacío, de lo contrario compilarán e informarán un error.
El punto clave del principio de sustitución de Richter es que no puede cubrir los métodos no abstractos de la clase principal. Cualquier método bien implementado en la clase principal está estableciendo una serie de especificaciones y contratos. Aunque no obliga a todas las subclases a cumplir con estas especificaciones, 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.
En la idea de diseño orientada a objetos, heredar esta característica trae una gran comodidad al diseño del sistema, pero también hay algunos riesgos que provienen de él. Los siguientes ejemplos se utilizan para ilustrar el riesgo de herencia. Necesitamos completar la función de restar dos números, y la clase A es responsable de ello.
Clase A {public int Func1 (int a, int b) {return AB; }} Cliente de clase pública {public static void main (string [] args) {a a = new a (); System.out.println ("100-50 ="+A.Func1 (100, 50)); System.out.println ("100-80 ="+A.Func1 (100, 80)); }} Resultados de ejecución:
100-50 = 50100-80 = 20
Más tarde, necesitamos agregar una nueva función: completar la adición de dos números, y luego sumar con 100, y la clase B es responsable. Es decir, la clase B necesita completar dos funciones:
Los dos números restan.
Agregue dos números y luego agregue 100.
Dado que la Clase A ha implementado la primera función, después de que Clase B hereda la Clase A, solo necesita completar la segunda función. El código es el siguiente:
La clase B extiende un {public int Func1 (int a, int b) {return a+b; } public int Func2 (int a, int b) {return func1 (a, b) +100; }} Cliente de clase pública {public static void main (string [] args) {b b = new b (); System.out.println ("100-50 ="+B.Func1 (100, 50)); System.out.println ("100-80 ="+B.Func1 (100, 80)); System.out.println ("100+20+100 ="+B.Func2 (100, 20)); }} Después de completar la clase B, el resultado de la ejecución:
100-50 = 150100-80 = 180100+20+100 = 220
Descubrimos que la función de sustracción que originalmente se estaba ejecutando normalmente tenía un error. La razón es que cuando la clase B nombró al método, reescribe accidentalmente el método de la clase principal, lo que hace que todos los códigos que ejecutan las funciones de sustracción llamen al método de reescritura de la clase B, causando errores en la función normal original. En este ejemplo, después de referirse a la función completada por la clase base A y cambiar a la subclase B, se produjo una excepción. En la programación real, a menudo completamos nuevas funciones reescribiendo el método de clase principal. Aunque es simple de escribir, la reutilización de todo el sistema de herencia será relativamente pobre, especialmente cuando el polimorfismo se usa con mayor frecuencia, la probabilidad de errores de operación del programa es muy alta. Si tiene que reescribir el método de la clase principal, el enfoque más común es: la clase original de la clase y la clase infantil heredan una clase base más popular, eliminan la relación de herencia original y usan dependencia, agregación, combinación y otras relaciones.