Recientemente, encontré dificultades en el proceso de aprendizaje de la interfaz PHP5. El libro dice que es una forma de implementar la herencia múltiple, pero todavía no sé cómo implementarla. Hay muy poca información sobre la interfaz PHP en Internet, así que verifiqué en Java. De hecho, son básicamente iguales. Después de leer el artículo "Aclaración de Java (interfaces y herencia)", de repente me di cuenta de que lo había entendido mal desde el principio. La llamada herencia múltiple se refiere a interfaces que heredan clases, no clases que heredan interfaces.
El artículo menciona la abstracción de OO. Al igual que la oración en el artículo: "La abstracción es eliminar la parte de la imagen", es muy vívida. Cuando pensaba en la abstracción, siempre pensé que era difícil de entender, pero la abstracción, jaja. , ahora es fácil de entender. Sí, esto es exactamente lo que hacen las interfaces y las clases abstractas.
Hay muchos otros puntos de vista en el artículo que me han beneficiado mucho, como se enumeran a continuación:
Creo que la esencia de la OO es la abstracción de objetos.
La función de la interfaz, en pocas palabras, es marcar el tipo de clase. Atribuir diferentes tipos de clases a diferentes interfaces puede administrarlas mejor.
El objetivo de la herencia también es la abstracción, no la reutilización del código.
Después de leer este artículo, básicamente entiendo cómo aplicar interfaces, clases abstractas y herencia.
El texto original es el siguiente:
Aclaración de Java (interfaces y herencia) Mi hermano, un estudiante de posgrado de segundo año en la Facultad de Ciencias de la Computación, habló conmigo sobre Java. Cuando nos reunimos, varias preguntas giraban en torno a las interfaces. ¿Por qué utilizar interfaces? ¿Cuándo debería utilizar interfaces? Me alegra que no me hayan preguntado cómo conectarme a SQL Server usando Java o cómo desarrollar aplicaciones J2EE. Estas preguntas son letales y deben evitarse. Este año, la Facultad de Ciencias de la Computación tiene un proyecto de graduación sobre J2ME. Los estudiantes que eligieron este tema todavía estaban estudiando el paquete java.util.* con una mueca a finales de mayo, esto y esto... suspiro.
La mayoría de la gente cree que el propósito de las interfaces es reemplazar la herencia múltiple. Como todos sabemos, Java no tiene un mecanismo de herencia múltiple como C++, pero puede implementar múltiples interfaces. De hecho, esto es inverosímil. Las interfaces y la herencia son cosas completamente diferentes. Las interfaces no tienen la capacidad de reemplazar la herencia múltiple y no tienen tal obligación. La función de la interfaz, en pocas palabras, es marcar el tipo de clase. Atribuir diferentes tipos de clases a diferentes interfaces puede administrarlas mejor. Creo que la esencia de OO es la abstracción de objetos, y la interfaz encarna mejor esto. La razón por la que discutimos patrones de diseño solo para lenguajes con capacidades abstractas (como c ++, java, c #, etc.) es porque lo que estudian los patrones de diseño es en realidad cómo abstraer razonablemente. (El famoso dicho del vaquero es "La abstracción es quitar la parte de la imagen", que parece una broma, pero en realidad es cierto).
El más básico de los patrones de diseño es el patrón Factory. En una aplicación muy simple que hice recientemente, quería hacer todo lo posible para que mi programa fuera portátil entre múltiples bases de datos. Por supuesto, esto implica muchos problemas, incluido el de compatibilidad de SQL. de diferentes DBMS es un dolor de cabeza. También podríamos simplificar el problema primero y considerar solo cómo conectar diferentes bases de datos.
Supongamos que tengo muchas clases, a saber, Mysql.java, SQLServer.java, Oracle.java y DB2.java. Se conectan a diferentes bases de datos respectivamente, devuelven un objeto de conexión de manera uniforme y todas tienen un método de cierre para cerrar la conexión. Sólo necesita seleccionar diferentes clases para su DBMS y podrá usarlo. ¿Pero qué base de datos usará mi usuario? No lo sé, lo que espero es modificar el código lo menos posible para satisfacer sus necesidades. Puedo abstraer la siguiente interfaz:
paquete org.bromon.test;
interfaz pública de base de datos
{
java.sql.Connection openDB (URL de cadena, Usuario de cadena, Contraseña de cadena);
cierre vacío();
}
Esta interfaz solo define dos métodos sin ningún código significativo. El código específico lo proporciona la clase que implementa esta interfaz, como Mysql.java:
Paquete org.bromon.test;
importar java.sql.*;
clase pública Mysql implementa DB
{
cadena privada url="jdbc:mysql:localhost:3306/test";
usuario de cadena privada = "raíz";
contraseña de cadena privada =””;
conexión de conexión privada;
Conexión pública openDB (url, usuario, contraseña)
{
//Código para conectarse a la base de datos}
public void close()
{
//Cerrar base de datos}
}
Los similares son, por supuesto, Oracle.java, etc. La interfaz DB clasifica estas clases. En la aplicación, definimos el objeto de esta manera:
org.bromon.test.DB myDB
usa myDB para operar la base de datos, y tú no. No tengo que preocuparme por eso. La clase que realmente estoy usando es la que se llama el principio "abierto-cerrado". Pero el problema es que no se puede crear una instancia de la interfaz, myDB=new DB(), dicho código es absolutamente incorrecto, solo podemos myDB=new Mysql() o myDB=new Oracle(). Lo siento, todavía necesito especificar qué clase se va a crear una instancia. Usar una interfaz es inútil. Entonces necesitamos una fábrica:
paquete org.bromon.test;
DBFactory de clase pública
{
Conexión de base de datos estática pública getConn()
{
Retorno(nuevo Mysql());
}
}
Entonces el código de creación de instancias se convierte en: myDB=DBFactory.getConn();
Esta es la fábrica ordinaria más básica entre los 23 modos. La clase de fábrica es responsable de instanciar específicamente qué clase y otra lógica del programa opera en la interfaz DB. Las responsabilidades se han transferido a la clase de fábrica. Por supuesto, también puede continuar definiendo la interfaz de fábrica y continuar asignando responsabilidades, lo que evoluciona hacia una fábrica abstracta.
La interfaz no es responsable de ninguna operación específica durante todo el proceso. Si otros programas quieren conectarse a la base de datos, solo necesitan construir un objeto DB, independientemente de cómo cambie la clase de fábrica. De esto se tratan las interfaces: de abstracción.
No hace falta decir que el concepto de herencia es fácil de entender. ¿Por qué heredar? ¿Porque quieres reutilizar el código? Definitivamente esta no es una razón. El objetivo de la herencia es la abstracción, no la reutilización del código. Si el objeto A tiene un método run(), el objeto B también quiere tener este método, por lo que alguien usa la Clase B extiende A. Este es un enfoque sin sentido. Si crea una instancia de A en B y llama al método Run() de A, ¿se puede lograr el mismo propósito? como sigue:
Clase B
{
A a=nueva A();
a.run();
}
Se trata de utilizar la agregación de clases para reutilizar código. Es el prototipo del modelo de delegación y una práctica que GoF siempre ha defendido.
Entonces, ¿cuál es el punto de la herencia? De hecho, esto se debe a razones históricas. El lenguaje OO original solo tenía herencia y no tenía interfaces, por lo que la abstracción solo se podía lograr mediante la herencia. Tenga en cuenta que la intención original de la herencia es la abstracción, no la reutilización del código (aunque la herencia también tiene esto). Efecto). Este es uno de los errores más graves de muchos libros malos de Java. No me he deshecho por completo de la sombra que han causado. Los libros malos son perjudiciales para las personas, especialmente los libros introductorios. ¿Cuándo debería utilizar la herencia? Úselo solo en clases abstractas, trate de no usarlo en otras situaciones. No se pueden crear instancias de clases abstractas. Solo proporcionan una plantilla, que ilustra el problema.
La raíz de todos los males en el desarrollo de software, especialmente entre los programadores de C++, es la duplicación de código en lugar de su reutilización y el mal uso de la herencia. El propósito de prohibir la herencia múltiple en Java es detener el mal uso de la herencia. Es un enfoque muy inteligente, pero mucha gente no lo entiende. Java puede reflejar mejor el diseño, que es una de las razones por las que estoy fascinado.