Tipo de conversión de objetos polimórficos Java <Br /> La conversión de tipo de objeto mencionada aquí se refiere a un objeto con una relación de herencia, no un objeto de ningún tipo. Al lanzar un objeto que no tiene una relación de herencia, el tiempo de ejecución de Java lanza una excepción de Java.Lang.ClasscastException.
En la cadena de herencia, llamamos la conversión de la subclase a la clase principal "transformación ascendente" y la conversión de la clase principal a la clase infantil "transformación hacia abajo".
Muchas veces, definimos las variables como el tipo de clase principal, pero se refieren al objeto de la clase infantil. Cuando el programa se ejecuta, utiliza un enlace dinámico para realizar los métodos de llamada a la subclase, es decir, polimorfismo.
Sin embargo, a veces para completar las funciones que algunas clases principales no tienen, necesitamos convertir los objetos de subclase transformados hacia arriba en subclases y llamar a los métodos de subclase, que es la transformación hacia abajo.
Nota: El objeto de la clase principal no se puede lanzar directamente a un tipo de subclase, y el objeto de subclase después de la transformación ascendente solo puede convertirse en un tipo de subclase nuevamente. En otras palabras, los objetos de subclase deben transformarse hacia arriba antes de que puedan transformarse hacia abajo. Consulte el siguiente código:
Public Class Demo {public static void main (string args []) {superclass superobj = new SuperClass (); Objeto principal.Elimine el comentario en la línea 7, y se lanzará una excepción en tiempo de ejecución, pero la compilación se puede aprobar.
Debido a que hay riesgos en la transición hacia abajo, al recibir una referencia a la clase principal, asegúrese de usar la instancia del operador para determinar si el objeto es la subclase que desea.
Public Class Demo {public static void main (string args []) {superclass superobj = new SuperClass (); = (SonClass) SuperObj; ) superobj; Resultados de ejecución:
① No se puede convertir
Resumen: la conversión de tipo de un objeto se verifica cuando se ejecuta el programa.
El polimorfismo de Java y la unión dinámica <Br /> En Java, las variables de la clase principal pueden referirse a instancias de la clase principal o instancias de la clase infantil.
Por favor, lea primero un código:
Public Class Demo {Public static void main (String [] args) {animal obj = new Animal (); .cry (); Call of Cat public void Cry () {System.out.println ("Meow ~"); }} Resultados de ejecución:
No sé cómo llamar a meow ~ lana ~
El código anterior define tres clases, a saber, las clases de animales, gatos y perros. La variable OBJ tiene un tipo de animal tipo, lo que puede señalar casos de clase animal, así como casos de clases de gatos y perros, lo cual es correcto. Es decir, las variables de la clase principal pueden referirse a instancias de la clase principal o instancias de la clase infantil. Tenga en cuenta que al revés está mal, porque todos los gatos son animales, pero no todos los animales son gatos.
Se puede ver que OBJ puede ser un humano, un gato o un perro. El polimorfismo se refiere a una cosa que tiene diferentes formas o formas.
Por ejemplo, los "humanos" también tienen muchas expresiones o implementaciones diferentes. , maestro, o médico en la próxima vida.
Hay tres condiciones necesarias para que existan el polimorfismo: la herencia, la reescritura y las variables principales se refieren a objetos de subclase.
Al llamar a un método utilizando un método polimórfico:
Primero verifique si el método está presente en la clase principal.
Si la subclase anula el método, se llama al método de la subclase, de lo contrario se llama al método de clase principal.
A partir del ejemplo anterior, podemos ver que una ventaja del polimorfismo es que cuando hay muchas subclases, no hay necesidad de definir múltiples variables. Mire el siguiente ejemplo:
Public Class Demo {public static void main (string [] args) {// Con la ayuda del polimorfismo, el propietario puede alimentar a muchos animales maestro ma = new Master (); ); ) {System.out.println ("Soy un animal pequeño, comiendo" + f.getfood ()); Un pequeño gato está comiendo " + f.getfood ());}} El perro de clase extiende animal {public void eat (alimentos f) {system.out.println (" Soy un perro, comiendo " + f. GetFood ())) ; String getFood () {return "hueso"; Resultados de ejecución:
Soy un animal pequeño, comiendo cosas, soy un pequeño gato, comiendo pescado, soy un perro, comiendo huesos
El método de alimentación de la clase magistral tiene dos parámetros, a saber, el tipo de animal y el tipo de comida. diferentes animales.
Vinculación dinámica
Para comprender la naturaleza del polimorfismo, hablemos sobre el proceso detallado de los métodos de llamadas de Java a continuación.
1) El compilador verifica el tipo de declaración y el nombre del método del objeto.
Supongamos que se llama obj.func (param), OBJ es un objeto de la clase CAT. Cabe señalar que puede haber múltiples métodos con nombres con FUNC pero diferentes parámetros. Por ejemplo, pueden existir métodos func (int) y func (string). El compilador enumerará todos los métodos nombrados FUNC en clase CAT y métodos que acceden a los atributos públicos y nombrados FUNC en su animal de clase principal.
De esta manera, el compilador obtiene una lista de todos los métodos candidatos posibles a llamar.
2) A continuación, el editor verificará la firma de parámetros proporcionada al llamar al método.
Si hay un método en todos los métodos llamados FUNC que coincida exactamente con la firma de parámetros proporcionada, entonces seleccione este método. Este proceso se llama resolución de sobrecarga. Por ejemplo, si se llama a func ("hola"), el compilador seleccionará func (string) en lugar de func (int). Debido a la existencia de la conversión de tipo automática, por ejemplo, INT se puede convertir en doble. Finalizar o múltiples métodos coincidir con él, luego compilar el error.
De esta manera, el compilador obtiene el nombre del método y la firma de parámetros que debe llamarse.
3) Si el modificador del método es privado, estático, final (estático y final se explicará más adelante), o un constructor, entonces el compilador podrá saber exactamente qué método debe llamarse. .
En consecuencia, el método llamado depende del tipo real del objeto e implementa la unión dinámica en tiempo de ejecución. Por ejemplo, al llamar a Func ("Hola"), el editor usará la vinculación dinámica para generar una directiva que llame a Func (String).
4) Cuando el programa se ejecuta y usa vinculación dinámica para llamar al método, el JVM definitivamente llamará al método de la clase que es más adecuado para el tipo real del objeto mencionado por OBJ. Hemos asumido que el tipo real de OBJ es CAT, que es una subclase de animal, y se llama si Func (String) se define en CAT, de lo contrario se buscará en la clase de animales y su clase padre.
Cada llamada al método requiere una búsqueda, lo cual es bastante costoso. De esta manera, cuando el método se llama realmente, la máquina virtual solo puede buscar esta tabla. En el ejemplo anterior, el JVM busca la tabla de métodos de la clase CAT para encontrar un método que coincida con la llamada a func ("hola"). Este método puede ser cat.func (string) o animal.func (cadena). Tenga en cuenta que si se llama a Super.func ("hola"), el compilador buscará la tabla de métodos de la clase principal.
Suponiendo que la clase animal contiene tres métodos: cry (), getName () y getage (), entonces su tabla de métodos es la siguiente:
Cry () -> animal.cry ()
getName () -> animal.getName ()
getAge () -> animal.getage ()
De hecho, Animal también tiene un objeto de clase principal predeterminado (que se explicará más adelante), que heredará el método de objeto, por lo que los métodos enumerados anteriormente no están completos.
Suponiendo que la clase CAT anula el método Cry () en la clase Animal y agrega un nuevo método Trewtree (), su lista de parámetros es:
Cry () -> Cat.cry ()
getName () -> animal.getName ()
getAge () -> animal.getage ()
escalado () -> cat.climbtree ()
Al ejecutar, el proceso de llamar al método obj.cry () es el siguiente:
El JVM primero accede a la tabla de métodos del tipo real de OBJ, que puede ser la tabla de métodos de la clase animal, o la tabla de métodos de la clase CAT y sus subclases.
JVM busca un método que coincida con Cry () en la tabla de métodos, y después de encontrarlo, sabrá a qué clase pertenece.
El JVM llama a este método.