Personalmente, las llamadas clases de programación son el mismo concepto que las clases en el mundo real que clasifican los objetos, pero se toman prestados en la programación. Las clases representan cosas que tienen una serie de puntos en común y las mismas operaciones o acciones, que son tipos de datos abstractos en la programación. Cada individuo específico (en el mundo real) y variables de instancia (para programación) son objetos.
Una clase es una representación de características comunes (atributos y operaciones) de ciertos objetos en el mundo real, y un objeto es una instancia de una clase.
Atributos de clase: es la abreviatura de los atributos estáticos de una clase, que se refiere a varios datos contenidos en la clase, como variables u otros objetos de clase;
Un servicio de clase: se llama función o método miembro.
¨
La forma de definición de una clase en Java es la siguiente:
[Modificador] Nombre de clase de clase [extiende la clase principal] [Implementa el nombre de la interfaz] {Declaración del método de clase de la variable de la clase del miembro de la clase}Hablemos de cada parte de esto en detalle:
Antes de la palabra clave de clase, los modificadores de clase generalmente se dividen en tres tipos: Modificadores de acceso de clase pública, modificador final (especificador de clase final) y modificador abstracto (especificador de clase abstracta)
Entre ellos, el modificador de permiso solo puede ser público o predeterminado (es decir, vacío, nada, lo que indica que se define como amigable), y el público significa que la clase se puede usar y acceder a cualquier parte (siempre que el programa pueda encontrar la ubicación de la clase), ya sea en el mismo paquete o en diferentes paquetes. Tenga en cuenta que esto es diferente de C ++. C ++ no tiene un modificador para restringir los derechos de acceso a la clase, sino que tiene derechos de acceso a las relaciones de herencia entre las clases. Además, todos tienen derechos de acceso a los atributos y métodos de clase. El permiso de acceso predeterminado (es decir, definido como amigable) significa que solo se puede hacer referencia y acceder por clases en el mismo paquete, pero no se puede acceder y hacer referencia por clases en otros paquetes, incluso si se importa.
También se mencionará más adelante: cuando se utiliza el modificador predeterminado de un atributo y método de clase, también se expresa que solo se puede hacer referencia y acceder a las clases en el mismo paquete.
No se permite la herencia múltiple en Java, que es diferente de C ++. Para compensar esta deficiencia, Java ha introducido el concepto de interfaz.
En la definición de la clase anterior, el cuerpo de la clase contiene principalmente el contenido específico de la clase, incluidos los atributos de la clase y los métodos de la clase. Las propiedades de una clase pueden ser variables o instancias simples de ciertas clases. Si es una instancia de una clase, se puede definir de la siguiente manera:
[Modificador] Nombre de nombre de clase Nombre de objeto = nuevo nombre de clase (lista de parámetros);
Al declarar objetos y variables complejas, no puede usar la creación durante las declaraciones, pero puede crearse en futuros constructores.
Los métodos definidos en una clase generalmente juegan dos roles: uno es realizar varias operaciones alrededor de los atributos de la clase; El otro es realizar intercambio de datos, entrega de mensajes y otras operaciones con otras clases u objetos.
La sintaxis para declarar métodos en Java es la siguiente:
[Modificador] Nombre del método del tipo de valor de retorno (Lista de parámetros) lanza Nombre de excepción 1, Nombre de excepción 2, ... {Método Body: Declaración de variable local; secuencia de declaración;}Los métodos de clase, también conocidos como funciones de miembros, se utilizan para especificar las operaciones de los atributos de clase e implementar funciones internas de las clases. También son una ventana importante para que las clases interactúen con el mundo exterior.
Los programadores de Java se centran en crear tipos definidos por el usuario llamados clases. Las clases también se llaman tipos definidos por programador. Cada clase contiene datos y un conjunto de métodos para manipular datos. La parte de datos en la clase se llama variables de instancia. Una instancia de un tipo definido por el usuario (es decir, una clase) se llama objeto.
Un objeto es una instancia de una clase. Una clase es una abstracción del mismo tipo de objeto y una plantilla para crear un objeto. Crear un objeto en el programa abrirá un espacio en la memoria, incluidas las propiedades y métodos del objeto. Cree un objeto usando el operador de palabras clave NUEVO.
Constructor (se puede comparar con C ++, que es casi lo mismo que C ++)
Crea tu propio constructor
• El nombre del constructor y el nombre de la clase son los mismos. Al construir un objeto de la clase de empleados, se inicia este constructor y se le asigna al campo de instancia un valor inicial. En Java, la definición y la inicialización están unificadas, ambos son indispensables.
Por ejemplo, al crear una instancia de la clase de empleado con el siguiente código,
nuevo empleado ("James Bond", 100000,1950,1,1);
Las características del constructor son:
(1) El constructor y la clase tienen el mismo nombre.
(2) Una clase puede tener múltiples constructores.
(3) El constructor puede tener 0, 1 o más parámetros.
(4) El constructor no tiene valor de retorno.
(5) El constructor siempre se llama con el nuevo operador.
El papel del constructor
(1) Inicialización de objetos
(2) Introducir más flexibilidad (asignación variable o operaciones más complejas)
(3) El constructor no se puede definir en Java
Un constructor no se puede definir en Java, y el sistema generará automáticamente un constructor predeterminado para el sistema. El nombre de este constructor es el mismo que el nombre de la clase, no tiene parámetros formales y no realiza ninguna operación.
Descripción general del método
Un programa Java está compuesto por definiciones de clase, y la clase tiene dos partes: propiedades y métodos. ¿Qué es una clase de descripción de atributo y qué es una clase de descripción de método? Cualquier objeto tiene memoria independiente para almacenar sus propiedades. Todos los objetos de la clase comparten el método almacenado en la memoria.
En otras palabras: los métodos son el componente principal de la clase. En una clase, el papel de un programa se refleja en el método.
El método es crear una subrutina nombrada por Java. Un método principal y varios sub-métodos. El método principal llama a otros métodos, y también se pueden llamar otros métodos entre sí, y el mismo método puede llamarse en cualquier momento por uno o más métodos.
Definir otro método en un método producirá un error de sintaxis.
(1) Es mejor evitar variables de instancia de "máscara" de variables locales. Esto se puede hacer sin usar el identificador del mismo nombre en una clase; Los parámetros en las llamadas del método se utilizan para pasar valores y referencias numéricas, y los métodos también se pueden llamar anidado y recursivamente.
(2) Si se especifica un tipo de valor de retorno no voide en el cuerpo del método, el método debe incluir una declaración de retorno para garantizar que haya un valor de retorno en cualquier caso, y la declaración de retorno no puede ser seguida por ninguna expresión;
La estructura básica de los programas Java es la siguiente:
Presentar la biblioteca de clase Java; Definir clase de usuario 1 {Definir varias variables u objetos de la clase 1: Defina el Método 1 de la clase 1; Definir el método 2 de la clase 1; ... Definir el método M1 de la clase 1; } Definir clase de usuario 2 {Definir varias variables u objetos de la clase 2: Defina el método 1 de la clase 2; Definir el método 2 de la clase 2; ... Defina el método M2 de la clase 2}Java introdujo el concepto de "modificador de control de acceso" que permite a los creadores de la biblioteca declarar lo que los programadores de clientes pueden utilizar y lo que no se puede utilizar.
Este nivel de control de acceso está entre el rango de "acceso máximo" y "acceso mínimo", que incluye: público, "predeterminado" (sin palabra clave), protegida y privada. La siguiente lista explica el significado de los modificadores de control de acceso:
Carácter de control de acceso público
Para las clases:
Solo hay un controlador de acceso para una clase en Java: público, es decir, público. Una clase se declara como una clase pública, lo que indica que puede ser accedida y referenciada por todas las demás clases. El acceso y la referencia aquí se refieren a que la clase sea visible y utilizable en su conjunto. Otras partes del programa pueden crear objetos de esta clase, acceder a variables de miembros visibles dentro de la clase y llamar a sus métodos visibles.
Una clase es visible para otras partes del programa en su conjunto, y no representa que todas las propiedades y métodos en la clase también sean visibles para otras partes del programa. El primero es solo una condición necesaria para el segundo. Si las propiedades y los métodos de la clase pueden acceder a las demás clases depende de los caracteres de control de acceso de estas propiedades y métodos.
Utilizado para propiedades en clase:
Los atributos en clase modificados con público se llaman atributos públicos. Si esta clase es una clase pública, todas las demás clases pueden acceder a ella.
Control de acceso predeterminado
Utilizado para clases
Si una clase no tiene caracteres de control de acceso, significa que tiene las características de control de acceso predeterminadas. Este control de acceso predeterminado estipula que la clase solo puede ser accedida y referenciada por clases en el mismo paquete, y no puede ser utilizado por clases en otros paquetes. Esta función de acceso se llama Accesibilidad al paquete. Al declarar los caracteres de control de acceso de la clase, toda la estructura del programa puede ser clara y rigurosa, reduciendo la posible interferencia y errores entre clases.
Utilizado para atributos de clase
Si las propiedades y métodos dentro de la clase no están limitados por los símbolos de control de acceso, también indican que son accesibilidad de paquetes.
3 personaje de control de acceso privado privado
Los atributos o métodos modificados con privado solo pueden ser accedidos y modificados por la clase misma, y no pueden ser obtenidos y referenciados por ninguna otra clase, incluidas las subclases de la clase.
1). Los datos privados, por ejemplo, tienen tres campos de instancia, que contienen datos que se operan dentro de una instancia de la clase de empleados.
nombre de cadena privada;
salario doble privado;
fecha privada contratada;
La palabra clave privada se utiliza para garantizar que la clase de empleados solo pueda acceder a estos campos de instancia.
2). Privar el método Al implementar la clase, hacemos que todos los campos de datos sean privados porque los datos públicos son peligrosos. ¿Cuál es la situación con el método? Aunque la mayoría de los métodos son públicos, los métodos privados también se usan con frecuencia. Estos métodos solo pueden separarse por el mismo método.
En resumen, el método privado se puede seleccionar en los siguientes casos:
(1) aquellos métodos que no están relacionados con el usuario de la clase.
(2) aquellos métodos que no son fáciles de mantener si se cambia la implementación de la clase.
Carácter de control de acceso protegido protegido
Las variables miembros modificadas con protegidas pueden ser referenciadas por tres tipos: la clase misma, otras clases en el mismo paquete que él y subclases de la clase en otros paquetes. El objetivo principal de usar el modificador protegido es permitir que sus subclases en otros paquetes accedan a propiedades específicas de la clase principal.
La palabra clave protegida nos presenta a un concepto llamado "herencia", que se basa en las clases existentes y agrega nuevos miembros sin afectar las clases existentes, llamamos a esta clase existente "clase base" o "clase base". También puede cambiar el comportamiento de los miembros existentes de esa clase. Para la herencia de una clase existente, decimos que nuestra nueva clase "extiende" la clase existente
Carácter privado de control de acceso protegido protegido privado
Privado y protegido se usan en secuencia para formar un carácter de control de acceso completo: carácter de control de acceso de protección privada. Las variables de los miembros modificadas con privateprotected pueden ser accedidas y referenciadas por dos clases, una es la clase misma y la otra son todas las subclases de la clase, ya sea que estas subclases estén en el mismo paquete que la clase o en otros paquetes.
En comparación con protegido, el modificador protegido privado excluye las no susclas dentro del mismo paquete desde el alcance accesible, lo que hace que las variables de los miembros sean más propietarias a clases con relaciones de herencia explícitas en lugar de paquetes que se agrupan libremente.
Modificador estático
La estática se llama modificador estático, que modifica propiedades y métodos en una clase.
El uso de la palabra clave estática puede cumplir con dos requisitos:
(1) Una situación es que solo desea usar un área de almacenamiento para guardar datos específicos, sin importar cuántos objetos desee crear, incluso no crea objetos en absoluto; Los atributos modificados por Static se denominan propiedades estáticas, y una de las características más esenciales de este tipo de atributo es que son atributos de una clase, no objetos específicos de ninguna clase. En otras palabras, para cualquier objeto específico de esta clase, una propiedad estática es una unidad de almacenamiento común. Cuando cualquier objeto de cualquier clase lo accede, obtiene el mismo valor numérico. Cuando cualquier objeto de cualquier clase lo modifica, también está haciendo operaciones en la misma unidad de memoria.
(2) Otra situación es que necesitamos un método especial que no esté asociado con ningún objeto de esta clase. Es decir, incluso si el objeto no se crea, es necesario un método que la clase puede llamar directamente.
Un propósito importante de Static es ayudarnos a llamar a ese método sin tener que crear un objeto.
Constantes estáticas
Las variables estáticas son raras. Sin embargo, las constantes estáticas son comunes. Por ejemplo, una constante estática se define en la clase de matemáticas:
Matemáticas de clase pública
{... public static final doble PI = 3.1.4159265358979323846;…} Un método estático declara que un método es estático tiene al menos tres significados:
(1) Cuando se usa este método, el nombre de la clase debe usarse como prefijo, en lugar de un nombre de objeto específico;
(2) Los métodos no estáticos son métodos que pertenecen a un objeto. Cuando se crea este objeto, el método del objeto tiene su propio segmento de código dedicado en la memoria; mientras que el método estático pertenece a toda la clase, y su segmento de código en la memoria se asignará y cargará de acuerdo con la definición de la clase y no será exclusivo de ningún objeto;
(3) Dado que el método estático pertenece a toda la clase, no puede manipular y procesar variables miembros que pertenecen a un determinado objeto, pero solo puede procesar variables miembros que pertenecen a toda la clase.
5 Método principal
El método principal no aplica operaciones a ningún objeto. De hecho, cuando el programa comienza a ejecutar, todavía no existen objetos. Se ejecuta el método estático y se construyen los objetos requeridos por el programa.
Indica que cada clase puede tener un método principal. Este es un truco muy conveniente para las clases de prueba unitaria.
Resumen es un modificador de resumen que se puede utilizar para modificar clases o métodos.
Clase abstracta
Cuando una clase se declara abstracta, esta clase se llama clase abstracta. La llamada clase abstracta es una clase sin objetos de instancia concretos.
Para abordar este problema, Java proporciona un mecanismo llamado "método abstracto". Pertenece a un método incompleto, con una sola declaración, y no tiene un cuerpo de método. Aquí está la sintaxis utilizada al declarar métodos abstractos:
abstracto void x ();
Métodos abstractos
Como modificador de método de clase, el resumen declara un método abstracto que solo tiene encabezados de método, pero no hay implementación de la operación del cuerpo y la operación del método específico.
Se puede ver que el método abstracto solo tiene la declaración del encabezado del método, y se utiliza un punto y coma para reemplazar la definición del cuerpo del método: en cuanto a la implementación específica del cuerpo del método, se completa con diferentes subclases de la clase actual en sus respectivas definiciones de clase.
Cabe señalar que todos los métodos abstractos deben existir en clases abstractas
medio.
Además de los métodos abstractos, las clases abstractas también pueden tener datos y métodos concretos.
Los métodos abstractos son conceptos muy importantes en el lenguaje de programación de Java. Lo usará de muchas maneras en la interfaz.
Nota: Aquí debemos comparar y memorizar con la interfaz. Los métodos en la interfaz son todos métodos abstractos. Por supuesto, también hay atributos en la interfaz, y sus propiedades específicas se describirán en detalle más adelante.
Clase final, atributo final, método final y finalizador (no hay modificador final en C ++)
Final es el modificador final, que modifica clases, propiedades y métodos. Además, las palabras clave del terminal son muy similares a la final y se introducirán juntas
Clase final
Si una clase se declara final, significa que no puede derivar nuevas subclases y no puede ser heredado como clase principal. Por lo tanto, una clase no puede declararse abstracta y final.
Las clases definidas como finales suelen ser algunas clases con funciones especiales que se utilizan para completar las funciones estándar. Definir una clase como final puede corregir su contenido, atributos y funciones y formar una relación de mapeo estable con su nombre de clase, asegurando así que las funciones implementadas al referirse a esta clase sean precisas.
Atributos finales
Muchos lenguajes de programación tienen sus propias formas de decirle al compilador que ciertos datos son una "constante". Las constantes se usan principalmente en los siguientes dos aspectos:
(1) Período de compilación constante, nunca cambiará;
(2) No queremos que un valor inicializado durante el tiempo de ejecución cambie.
Un campo de instancia se puede definir como final (no se puede cambiar). Este campo debe inicializarse cuando se construye el objeto. Es decir, debe asegurarse que el valor se haya establecido antes del final de cada constructor. El valor del campo no se puede cambiar en el futuro
Método final
La razón para usar el método final puede deberse a consideraciones por dos razones.
El primero es "bloquear" el método para evitar que cualquier clase de herencia cambie su significado original. Al diseñar un programa, esta práctica se puede tomar si desea que el comportamiento de un método permanezca sin cambios durante la herencia y no se pueda sobrescribir o reescribir.
La segunda razón para adoptar el método final es la eficiencia de la ejecución del programa.
Terminador
La función del terminator es un método ejecutado al recuperar objetos. Similar al método que los constructores se ejecutan al crear objetos.
ejemplo
protegido voidFinalize () {System.out.println (""); }Otros modificadores
volátil
Si un atributo se modifica por un volátil, significa que este atributo puede ser controlado y modificado por varios hilos al mismo tiempo.
sincronizado
Utilizado principalmente para la sincronización de hilos
nativo
Significa que el método no está escrito en lenguaje Java (está escrito en C, C ++ y otros idiomas)
Alguna información encontrada en línea: - Categoría interna
En pocas palabras, las clases internas son clases en clases, por ejemplo:
Clase A {private int i; private void m () {} clase B {mm (int j) {i = j; m ();}}}Aquí, B es la clase interna de A, que se caracteriza por un acceso conveniente a métodos y propiedades privadas en clases externas. Por ejemplo, aquí B puede acceder directamente a las propiedades privadas I y los métodos privados M () en A.
Las características más importantes de la programación orientada a objetos son la encapsulación (también llamada abstracción), herencia y polimorfismo. Como lenguaje de programación orientado a objetos, Java tiene sus propias ventajas a este respecto:
"La herencia es una forma de reutilización de software, que es efectiva para reducir la complejidad del software. La herencia también es una característica de un lenguaje de programación orientado a objetos. Lenguajes que adoptan objetos pero que no tienen herencia son lenguajes basados en objetos, pero no lenguajes orientados a objetos. Esta es la diferencia entre los dos".
La relación de herencia entre las clases es una simulación directa de las relaciones genéticas en el mundo real. Representa la conexión intrínseca entre las clases y el intercambio de atributos y operaciones, es decir, las subclases pueden seguir ciertas características de la clase principal (clase hereditaria). Por supuesto, las subclases también pueden tener sus propias propiedades y operaciones independientes
La herencia es una forma de reutilización de software. Las clases existentes generan nuevas clases, y se agregan nuevos atributos y comportamientos reteniendo sus propiedades y comportamientos, y modificando el rendimiento de acuerdo con los requisitos de la nueva clase. Si una clase infantil hereda solo de una clase de padres, se llama herencia única; Si una clase infantil hereda de más de una clase de padres, se llama multi-herencia. Tenga en cuenta que Java no admite la herencia múltiple, pero admite el concepto de "interfaz". Las interfaces permiten a Java obtener muchas ventajas de la herencia múltiple y abandonar las desventajas correspondientes. Nota: C ++ admite múltiples herencias
Definición de relación de herencia:
[Modificador] El nombre de la subclase de clase extiende el nombre de la clase principal, Nombre de la clase principal 2
El nombre de la clase principal sigue se extiende
La palabra clave se usa para indicar qué subclase de la clase actual ya está allí, y hay una relación de herencia.
Defina dos subclases de empleados de la clase de empleados:
Categoría de empleados generales: CommonEmployee
Categoría de supervisor: GerenteMeployee
Hay dos aspectos principales de la herencia de la subclase de la clase principal:
(1) Herencia de atributos. Por ejemplo, una empresa es una clase matriz, y una empresa tiene un nombre, dirección, gerente, empleado, etc., que son todos aspectos estructurales.
(2) Herencia del método. Una clase principal define varias operaciones, como una empresa que necesita tener proyectos, ganancias, nombramiento de gerentes, empleados de reclutar, etc., y la subsidiaria también heredará estas acciones S; MP
ClassCommonEmployeEteExtends Empleado // Subclase 1: {intm_managerno; // Defina el atributo de clase M_Managerno, que representa el número de jefe de empleados} classManagerEmpeEteeExtends Empleado // Subclase 2: {INTM_SECRETARYNO; // Defina la atributo de clase M_secretaryno, que representa el número de secretario} Herencia de atributos y escondite
Aunque la clase de empleados es una clase de padres, no significa que tenga más funciones solo porque es una clase de padres. Por el contrario, los subanalogs tienen más funciones que sus clases de padres. Debido a que la subclase es una extensión de la clase principal, los atributos y los métodos que la clase principal no tiene se agregan (1) la subclase no puede acceder al miembro privado de la clase principal, pero la subclase puede acceder al público de su clase principal.
(2) El acceso protegido es un nivel intermedio protector entre el acceso público y privado.
(3) Dado que los miembros de la clase principal heredada no figuran en la declaración de subclase, estos miembros existen en la subclase.
Aquí, debemos distinguir entre herencia, sobrescribir y sobrecargar, varios conceptos confusos:
Solo en el nivel conceptual de método se pueden confundir fácilmente estos tres conceptos:
Herencia de método
Para los objetos de subclase, se pueden usar métodos de la clase principal. Incluso si estos métodos no están claramente definidos en la subclase, se heredan automáticamente de la clase principal.
Cobertura de método
La anulación del método se refiere a: un método que define un método con el mismo nombre para sobrescribir la clase principal, que es una implementación de la tecnología polimórfica. Cuando el método de la clase principal se sobrescribe en la clase infantil, generalmente es la versión de clase infantil la que llama a la versión de la clase principal y hace algún trabajo adicional.
Hay muchas cosas a tener en cuenta. Aquí, principalmente menciono esto y Super. Hay esto en C ++ (y el concepto es similar al de Java), pero no hay Super.
Esto representa el objeto actual en sí, y esto representa una referencia al objeto actual. Se puede entender como otro nombre del objeto. Esto le permite llamar a los métodos y propiedades del objeto actual.
Por ejemplo: this.getName () y getName () son los mismos en la clase.
Super representa el objeto de clase principal directa del objeto actual, y es la sobrecarga del método de referencia del objeto de clase principal del objeto actual.
Definición de sobrecarga: el método se puede definir con el mismo nombre del método pero diferentes tablas de parámetros (el número, tipo o orden de parámetros en la tabla de parámetros tiene diferentes valores), que se denomina sobrecarga del método.
• Sobrecarga: la sobrecarga se produce cuando múltiples métodos tienen el mismo nombre y contienen diferentes parámetros. El compilador debe elegir qué método llamar. Elige el método correcto comparando los tipos de parámetros en diferentes encabezados de método con los tipos de valores utilizados en llamadas de método específicos.
El polimorfismo permite el procesamiento de variables existentes y clases relacionadas en un estilo unificado, lo que facilita agregar nuevas características en el sistema. Aquí, publicar la información que encontró en línea puede aclarar más claramente los polimorfismos y problemas de herencia que necesitan atención especial en la herencia:
Polimorfismos de Java
La programación orientada a objetos tiene tres características, a saber, encapsulación, herencia y polimorfismo.
La encapsulación oculta el mecanismo de implementación interna de la clase, de modo que la estructura interna de la clase se puede cambiar sin afectar al usuario, al tiempo que protege los datos.
La herencia es reutilizar el código de clase principal mientras se prepara para la implementación del polimorfismo. Entonces, ¿qué es el polimorfismo?
El método reescritura, sobrecarga y conexión dinámica constituyen polimorfismo. Una de las razones por las cuales Java introdujo el concepto de polimorfismo es que es diferente de C ++ en términos de herencia de clase. Este último permite la herencia múltiple, lo que le brinda funciones muy poderosas, pero la compleja relación de herencia también trae mayores problemas a los desarrolladores de C ++. Para evitar riesgos, Java solo permite una herencia única, y existe una relación IS-A entre las clases derivadas y las clases base (es decir, "gatos" es un "animal"). Aunque hacer esto garantiza la simplicidad y la claridad de la relación de herencia, inevitablemente tendrá grandes limitaciones funcionales. Por lo tanto, Java introdujo el concepto de polimorfismo para compensar esta deficiencia. Además, las clases e interfaces abstractas también son medios importantes para resolver las limitaciones de las regulaciones de herencia única. Al mismo tiempo, el polimorfismo es también la esencia de la programación orientada a objetos.
Para comprender el polimorfismo, primero debes saber qué es la "transformación ascendente".
Definí un gato de subclase, que hereda la clase de animales, y el último es que el primero es la clase padre. Puedo pasar
Cat C = nuevo Cat ();
Instanciar un objeto de gato no es difícil de entender. Pero cuando lo defino así:
Animal a = nuevo gato ();
¿Qué quiere decir esto?
Es simple, significa que defino una referencia de tipo animal a un objeto de tipo de gato recién creado. Dado que el gato se hereda de su animal de clase principal, una referencia a un tipo de animal puede apuntar a un objeto de un tipo de gato. Entonces, ¿cuál es el punto de hacer esto? Debido a que las subclases son una mejora y extensión para la clase principal, las subclases son generalmente más poderosas que las clases de los padres en función, y sus atributos son más únicos que las clases de los padres.
La definición de una referencia a un tipo de clase principal apunta a un objeto que se subclasia no solo puede usar las funciones poderosas de la subclase, sino también extraer los puntos en común de la clase principal.
Por lo tanto, una referencia al tipo de clase principal puede llamar a todas las propiedades y métodos definidos en la clase principal, y está impotente para los métodos definidos en la clase infantil pero no en la clase principal;
Al mismo tiempo, un método en la clase principal solo puede llamarse por una referencia al tipo de clase principal si se define en la clase principal pero no se anula en la clase infantil;
Para los métodos definidos en la clase principal, si el método se reescribe en la clase infantil, la referencia al tipo de clase principal llamará a este método en la clase infantil, que es una conexión dinámica.
Mire el siguiente programa:
clase Padre {public void func1 () {func2 (); } // Este es el método func () en la clase principal, debido a que el método se anula en la subclase a continuación //, por lo tanto, cuando se le llama en la referencia del tipo de clase principal, este método ya no será válido // reemplazar el método func () destinado en la subclase public void func2 () {System.out.Println ("AAA");; }} class Child extiende el padre {// func1 (int i) es una sobrecarga del método func1 () // Dado que este método no está definido en la clase principal, no se puede llamar mediante la referencia del tipo de clase principal // en el método principal a continuación. } // func2 () reescribe el método func () en el padre de la clase principal // Si el método func () se llama en la referencia al tipo de clase principal, debe ser el método reescritado en la subclase public void func2 () {System.out.println ("CCC"); }} clase pública PolyMorphismTest {public static void main (string [] args) {padre child = new Child (); Child.func1 (); // ¿Cuál será el resultado de la impresión? }}El programa anterior es un ejemplo muy típico de polimorfismo. El niño de la clase infantil hereda el padre de la clase principal, sobrecarga el método de clase principal func1 () y sobrescribe el método de clase principal func2 (). La función sobrecargada (Int I) y Func1 () ya no son el mismo método. Como no hay func1 (int i) en la clase principal, el niño de referencia del tipo de clase principal no puede llamar al método Func1 (int i). Si la subclase anula el método func (), entonces el niño de referencia del tipo de clase principal llamará al funcc2 () reescrito en la subclase cuando llame al método.
Entonces, ¿qué resultados imprimirá el programa?
Obviamente, debería ser "CCC".
Para el polimorfismo, se puede resumir como:
(1) use referencias del tipo de clase principal para apuntar al objeto de la subclase (objeto real);
(2) Esta referencia solo puede llamar a métodos y variables definidas en la clase principal;
(3) Si se reescribe un método en la clase principal en la subclase, luego, cuando llame a este método, se llamará al método en la subclase; (conexión dinámica, llamada dinámica)
(4) Las variables no se pueden reescribir (anuladas). El concepto de "reescribir" es solo para métodos. Si las variables en la clase principal son "reescritas" en la subclase, se informará un error durante la compilación.
El polimorfismo es a través de:
(1) la interfaz e implementar la interfaz e sobrescribir varias clases diferentes que cubren el mismo método en la interfaz (2) la clase principal y la clase principal y la clase principal y sobrescriben varias subclases diferentes que cubren el mismo método en la clase principal.
1. Conceptos básicos
Polimorfismo: envíe un mensaje a un objeto y deje que el objeto decida a qué comportamiento responder.
Las llamadas de método dinámico se implementan asignando referencias de objetos de subclase a variables de referencia de objetos de superclase.
Este mecanismo de AVA sigue un principio: cuando un objeto de superclase se refiere a una variable para referirse a un objeto de subclase, el tipo de objeto referenciado en lugar del tipo de la variable referenciada determina cuyo método miembro se llama, pero el método llamado debe definirse en la superclase, es decir, el método cubierto por la subclase.
(1) Si A es una referencia a la Clase A, A puede apuntar a una instancia de la Clase A, o una subclase de la Clase A.
(2) Si A es una referencia a la interfaz A, entonces A debe apuntar a una instancia de una clase que implementa la interfaz A.
Mecanismo de implementación del polimorfismo de Java
Mecanismo de implementación JVM actual de Sun, la referencia de una instancia de clase es un puntero a un mango, que es un par de punteros:
Un puntero apunta a una tabla, y de hecho, esta tabla también tiene dos punteros (un puntero apunta a una tabla de método que contiene el objeto y el otro puntero a un objeto de clase, que indica el tipo al que pertenece el objeto);
Otro puntero apunta a un espacio de memoria asignado desde el montón de Java.
Resumir
(1) Las llamadas de método dinámico se implementan asignando referencias de objetos de subclase a variables de referencia de objetos de superclase.
DerivedC c2 = new DerivedC (); Baseclass A1 = C2; // clase base de base, derivado es a1.play () heredado de baseclass; //play() is defined in BaseClass and DerivedC, that is, the subclass overrides the method
analizar:
* 为什么子类的类型的对象实例可以覆给超类引用?
自动实现向上转型。通过该语句,编译器自动将子类实例向上移动,成为通用类型BaseClass;
* a. Will play() execute a method defined by the subclass or a parent class?
子类的。在运行时期,将根据a这个对象引用实际的类型来获取对应的方法。所以才有多态性。一个基类的对象引用,被赋予不同的子类对象引用,执行该方法时,将表现出不同的行为。
在a1=c2的时候,仍然是存在两个句柄,a1和c2,但是a1和c2拥有同一块数据内存块和不同的函数表。
(2)不能把父类对象引用赋给子类对象引用变量
BaseClass a2=new BaseClass(); DerivedC c1=a2;//出错
在java里面,向上转型是自动进行的,但是向下转型却不是,需要我们自己定义强制进行。
c1=(DerivedC)a2; 进行强制转化,也就是向下转型.
(3)记住一个很简单又很复杂的规则,一个类型引用只能引用引用类型自身含有的方法和变量。
你可能说这个规则不对的,因为父类引用指向子类对象的时候,最后执行的是子类的方法的。
其实这并不矛盾,那是因为采用了后期绑定,动态运行的时候又根据型别去调用了子类的方法。而假若子类的这个方法在父类中并没有定义,则会出错。
例如,DerivedC类在继承BaseClass中定义的函数外,还增加了几个函数(例如myFun())
analizar:
当你使用父类引用指向子类的时候,其实jvm已经使用了编译器产生的类型信息调整转换了。
这里你可以这样理解,相当于把不是父类中含有的函数从虚拟函数表中设置为不可见的。注意有可能虚拟函数表中有些函数地址由于在子类中已经被改写了,所以对象虚拟函数表中虚拟函数项目地址已经被设置为子类中完成的方法体的地址了。
(4)Java与C++多态性的比较
jvm关于多态性支持解决方法是和c++中几乎一样的,
只是c++中编译器很多是把类型信息和虚拟函数信息都放在一个虚拟函数表中,但是利用某种技术来区别。
Java把类型信息和函数信息分开放。Java中在继承以后,子类会重新设置自己的虚拟函数表,这个虚拟函数表中的项目有由两部分组成。从父类继承的虚拟函数和子类自己的虚拟函数。
虚拟函数调用是经过虚拟函数表间接调用的,所以才得以实现多态的。
Java的所有函数,除了被声明为final的,都是用后期绑定。
1个行为,不同的对象,他们具体体现出来的方式不一样,
比如: 方法重载overloading 以及方法重写(覆盖)override
class Human{ void run(){输出人在跑} } class Man extends Human{ void run(){输出男人在跑} } 这个时候,同是跑,不同的对象,不一样(这个是方法覆盖的例子) class Test{ void out(String str){输出str} void out(int i){输出i} }这个例子是方法重载,方法名相同,参数表不同
ok,明白了这些还不够,还用人在跑举例
Human ahuman=new Man();
这样我等于实例化了一个Man的对象,并声明了一个Human的引用,让它去指向Man这个对象意思是说,把Man这个对象当Human看了.
比如去动物园,你看见了一个动物,不知道它是什么, "这是什么动物? " "这是大熊猫! "
这2句话,就是最好的证明,因为不知道它是大熊猫,但知道它的父类是动物,所以,
这个大熊猫对象,你把它当成其父类动物看,这样子合情合理.
这种方式下要注意new Man();的确实例化了Man对象,所以ahuman.run()这个方法输出的是"男人在跑"
如果在子类Man下你写了一些它独有的方法比如eat(),而Human没有这个方法,
在调用eat方法时,一定要注意强制类型转换((Man)ahuman).eat(),这样才可以...
对接口来说,情况是类似的...
Ejemplo:
package domain; //Define superA class superA { int i = 100; void fun(int j) { j = i; System.out.println("This is superA"); } } //Define superA subclass subB class subB extends superA { int m = 1; void fun(int aa) { System.out.println("This is subB"); } } //Define superA subC class subC extends superA { int n = 1; void fun(int cc) { System.out.println("This is subB"); } } //Define superA subC class subC extends superA { int n = 1; void fun(int cc) { System.out.println("This is subC"); } } class Test { public static void main(String[] args) { superA a = new superA(); subB b = new subB(); subC c = new subC(); a = b; a.fun(100); a = c; a.fun(200); }} /*
* 上述代码中subB和subC是超类superA的子类,我们在类Test中声明了3个引用变量a, b,
* c,通过将子类对象引用赋值给超类对象引用变量来实现动态方法调用。也许有人会问:
* "为什么(1)和(2)不输出:This is superA"。
* java的这种机制遵循一个原则:当超类对象引用变量引用子类对象时,
* 被引用对象的类型而不是引用变量的类型决定了调用谁的成员方法,
* 但是这个被调用的方法必须是在超类中定义过的,
* 也就是说被子类覆盖的方法。
* 所以,不要被上例中(1)和(2)所迷惑,虽然写成a.fun(),但是由于(1)中的a被b赋值,
* 指向了子类subB的一个实例,因而(1)所调用的fun()实际上是子类subB的成员方法fun(),
* 它覆盖了超类superA的成员方法fun();同样(2)调用的是子类subC的成员方法fun()。
* 另外,如果子类继承的超类是一个抽象类,虽然抽象类不能通过new操作符实例化,
* 但是可以创建抽象类的对象引用指向子类对象,以实现运行时多态性。具体的实现方法同上例。
* 不过,抽象类的子类必须覆盖实现超类中的所有的抽象方法,
* 否则子类必须被abstract修饰符修饰,当然也就不能被实例化了
*/
以上大多数是以子类覆盖父类的方法实现多态.下面是另一种实现多态的方法-----------重写父类方法
JAVA里没有多继承,一个类之能有一个父类。而继承的表现就是多态。一个父类可以有多个子类,而在子类里可以重写父类的方法(例如方法print()),这样每个子类里重写的代码不一样,自然表现形式就不一样。这样用父类的变量去引用不同的子类,在调用这个相同的方法print()的时候得到的结果和表现形式就不一样了,这就是多态,相同的消息(也就是调用相同的方法)会有不同的结果。举例说明:
//Premary class public class Father{ //The parent class has a method to hit the child public void hitChild(){ } } //Subclass 1 public class Son1 extends Father{ //Rewrite the method to hit the child public void hitChild(){ System.out.println("Why hit me? What I did wrong!"); } } //Subclass 2 public class Son2 extends Father{ //Rewrite the method to hit the child public void hitChild(){ System.out.println("I know I'm wrong, stop hitting it!"); } } //Subclass 3 public class Son3 extends Father{ //Rewrite the parent class hits the child method public void hitChild(){ System.out.println("I run, you can't hit!"); } } //Test class public class Test{ public static void main(String args[]){ Father father; father = new Son1(); father.hitChild(); father = new Son2(); father.hitChild(); father = new Son3(); father.hitChild(); }}都调用了相同的方法,出现了不同的结果!这就是多态的表现!
import java.io.*;class Super{ Super(){ System.out.println("This is super class!"); } void method(){ System.out.println("Super's method"); }}class Sub extends Super{ Sub(){ super(); System.out.println("/n/t:and here is the child"); } void method(){ System.out.println("child's method"); }}public class Super_Sub{ public static void main(String[] args){ Super sup=new Sub(); sup.method(); Sub child=(Sub)new Super();//Here, the actual allocated memory is Super, but Child is used to refer to it. This is "downward transformation" (the parent class impersonates a child class, because the subclass is down when drawing in UML), and it must be casted by child.method(); }}对于数据来说,继承是否为正确的设计可以用一个简单的规则来判断。“is-a”规则表明子类的每一个对象都是一个超类的对象。例如,每一个经理是一个员工。然而,只有经理类是员工类的子类才是有意义的。很明显,反过来就不行了――并不是每个员工都是经理。
还有一个明确叙述“is-a”规则的方法是替代原则。该原则规定无论何时,如果程序需要一个超类对象,都可以用一个子类对象来代替
动态绑定
理解调用一个对象方法的机制是非常重要的。下面具体介绍:Xf;
(1)编译器检查对象的声明类型和方法名。
(2) Next, the compiler checks the parameter type in the method call. If one of all methods called f has a parameter type whose parameter type best matches the parameter type provided by the call, the method will be selected to call. This process is called overload selection. (estático)
(3)当程序运行并且使用动态绑定来调用一个方法时,那么虚拟机必须调用同x所指向的对象的实际类型相匹配的方法版本。
...
如果类中没有写构造函数,那么系统会自动为该类提供一个默认构造函数,该构造函数将所有的实例字段初始化为默认值:
...
包用途:
Java允许把多个类收集在一起成为一组,称作包(package)。包便于组织任务,以及使自己的任务和其他人提供的代码库相分离。
标准Java库被分类成许多的包,其中包括java.1ang、java.util和java.net等等。标准Java包是分层次的。就像在硬盘上嵌套有各级子目录一样,可以通过层次嵌套组织包。所有的Java包都在Java和Javax包层次内
创建包
已经看到,已有的库,比如JavaAPI中的类和接口,可以导入到Java程序中。
Java API中的每一个类和接口属于一个特定的包。它包含一组相关联的类和接口,实际是对类和接口进行组织的目录结构。
例如,假定文件名是MyClass.java。它意味着在那个文件有一个、而且只能有一个public类。而且那个类的名字必须是MyClass(包括大小写形式):
packagemypackage;publicclass MyClass{……}创建可复用的类的步骤简要说明如下:
(1)定义一个public类。如果类不是public,它只能被同一包中的其他类使用。
(2)选择一个包名,并把package语句加到可复用的类的源代码文件中。
(3)编译这个类。这样,它就被放到适当的包目录结构中,以供编译器和解译器使用。
(4)把这个可复用的类导入到需要用它的程序中。现在就可以使用它了。
注意在Java语言中可以出现在类定义的括号外面的仅有两个语句,它们是package和import。
包引用---每个类名前加上完整的包名
例如,给出一个指向此包中的类的快捷方式。一旦使用import(导入)了以后,就不再需要给出完整的包名。
可以引入一个特定的类,也可以引入整个包。import语句要放在源文件的头部(但在所有package语句的下面)。例如,可以通过下面的语句引入在java.util包中的所有的类:
importjava.util.*;
然后,就可以使用
Datetoday=new Date();
而不需要在前面加上包名。也可以引入包中某个特定的类:
importjava.util.Date;
要把类放人一个包中,必须把此包的名字放在源文件头部,并且放在对包中的类进行定义的代码之前。例如,在文件Employee.java的开始部分如下:
packagecom.horstmann.corejava;publicclass Employee{……}把包中的文件放入与此完整的包名相匹配的子目录中。例如,在包com.horstmann.corejava中的所有的类文件都必须放在子目录com/horstmann/core.java(Windows下的com/horstmann/corejava)下。这是最简单的一种方法
类被存储在文件系统的子目录中。类的路径必须与所在包名相匹配。
在前面的例子中,包目录com/horstmann/corejava是程序目录的一个子目录。然而这样安排很不灵活。一般,有多个程序需要访问包文件。为了使包可以在多个程序间共享,需要做以下事情:
1)把类放在一个或多个特定的目录中,比如/home/user/classdir。此目录是包树的基本目录。如果加入了类com.horstmann.corejava.Employee,那么此类文件必须位于子目录/home/user/classdir/com/horstmann/corejava下。
2)设置类路径。类路径是其子目录包含类文件的所有基本目录的集合。classpath
已经接触过public和private访问指示符。
被标记为Public的部件可以被任何类使用,而私有部件只能被定义它们的类使用。如果没有指定public或private,那么部件(即类、方法或变量)可以被同一个包中的所有方法访问。
Java API包
为了简化面向对象的编程过程,Java系统事先设计并实现了一些体现了常用功能的标准类,如用于输入/输出的类,用于数学运算的类,用于图形用户界面设计的类,用于网络处理的类等。这些系统标准类根据实现的功能不同,可以划分成不同的集合,每个集合是一个包,合称为类库。可以引用这些包,也可以创建自己的包。
Java的类库是系统提供的已实现的标准类的集合,是Java编程的API,它可以帮助开发者方便、快捷地开发Java程序
接口主要作用是可以帮助实现类似于类的多重继承的功能。在Java中,出于简化程序结构的考虑,不再支持类间的多重继承而只支持单重继承,即一个类至多只能有一个直接父类。然而在解决实际问题的过程中,仅仅依靠单重继承在很多情况下都不能将问题的复杂性表述完整,需要其他的机制作为辅助。
接口声明
Java中声明接口的语法如下:
[public] interface 接口名[extends 父接口名列表]{ //接口体;//常量域声明[public] [static] [final] 域类型域名=常量值; //抽象方法声明[public] [abstract] 返回值方法名(参数列表) [throw异常列表];}从上面的语法规定可以看出,定义接口与定义类非常相似,实际上完全可以把接口理解成为一种特殊的类,接口是由常量和抽象方法组成的特殊类
(1)接口中的属性都是用final修饰的常量,
(2)接口中的方法都是用abstract修饰的抽象方法,在接口中只能给出这些抽象方法的方法名、返回值和参数列表,而不能定义方法体,即仅仅规定了一组信息交换、传输和处理的“接口”
接口的实现
一个类要实现某个或某几个接口时,有如下的步骤和注意事项:
(1)在类的声明部分,用implements关键字声明该类将要实现哪些接口;
como sigue:
class类名implements接口{ }(2)如果实现某接口的类不是abstract的抽象类,则在类的定义部分必须实现指定接口的所有抽象方法,即为所有抽象方法定义方法体,而且方法头部分应该与接口中的定义完全一致,即有完全相同的返回值和参数列表;
(3)如果实现某接口的类是abstract的抽象类,则它可以不实现该接口所有的方法。
(4)一个类在实现某接口的抽象方法时,必须使用完全相同的方法头。
(5)接口的抽象方法,其访问限制符都已指定是public,所以类在实现方法时,必须显式地使用public修饰符。
resumen:
多重继承是指一个子类继承多个父类。Java不支持多重继承,但Java提供了接口。
子类不能访问父类的private成员,但子类可以访问其父类的public,protected和包访问成员;要访问父类的包访问成员,子类一定要在父类的包内。
子类构造函数总是先调用(显式的或隐式地)其父类的构造函数,以创建和初始化子类的父类成员。
子类的对象可以当作其父类的对象对待,反之则不行(即向上转型)
protected访问是public和private访问之间一个保护性的中间层次。父类方法、子类方法和在同一个包内类的方法都能访问父类的protected成员,但其他方法均不能访问
一个子类对象引用可以隐式地转换成一个父类对象引用。使用显式的类型转换,可以把父类引用转换成子类引用。如果目标不是子类对象,将产生ClassCastException例外处理。