Anteriormente usamos clases para crear nuevos tipos y usamos la herencia para facilitar nuestro proceso de creación de clases. En esta conferencia profundizaré en los tipos e introduciré el concepto de polimorfismo.
verificación de tipos
Cualquier variable y referencia en Java solo se puede utilizar después de pasar una declaración de tipo. Hemos visto antes que los datos de objetos, los datos de clases, los parámetros de métodos, los valores de retorno de métodos y las variables automáticas dentro de los métodos necesitan declarar sus tipos. Java es un lenguaje fuertemente tipado, que verifica tipos. Si utilizamos el tipo incorrecto, provocará errores.
El tipo no coincide, la ternura no es válida.
Por ejemplo, en la clase de Prueba siguiente, asignamos un objeto de clase Copa a una referencia de clase Persona:
prueba de clase pública{ public static void main(String[] args) { Human aPerson; aPerson = new Cup() }}class Human { /** * constructor */ public Human(int h) { this.height = h; } /** * descriptor de acceso */ public int getHeight() { return this.height } /** * mutator */ public void growHeight(int h) { this.height = this.height + h } privado; int altura;}clase Copa { public void addWater(int w) { this.water = this.water + w } public void beberAgua(int w) { this.water = this.water - w } private int water = 0; ;}
javac devolverá:
encontrado: Cuprequired: Human aPerson = new Cup();
Conversión de tipo básico
Java puede realizar conversión de tipos en variables de tipos básicos. Los diferentes tipos básicos tienen diferentes longitudes y rangos de almacenamiento. Si convertimos de un tipo de alta precisión a un tipo de baja precisión, como la conversión de float a int, podemos perder información. Esta conversión se denomina conversión estrecha. En este caso, necesitamos declarar explícitamente la conversión de tipo, como por ejemplo:
prueba de clase pública{ public static void main(String[] args) { int a; a = (int) 1.23 // reducción de conversión System.out.println(a }}
Si convertimos de un tipo de baja precisión a uno de alta precisión, no hay preocupación por la pérdida de información. Esta transformación se denomina conversión ampliada. No necesitamos requerir explícitamente la conversión de tipos, Java puede hacerlo automáticamente:
prueba de clase pública{ public static void main(String[] args) { int a = 3; double b = a; ampliación de conversión System.out.println(a);
Conversión de tipo básico
upcast y polimorfismo
En Java, las referencias también pueden ser tipográficas, pero existen restricciones.
Podemos convertir una referencia de clase derivada a su referencia de clase base, lo que se denomina conversión ascendente o relajada. La siguiente clase BrokenCup hereda de la clase Cup y anula los métodos addWater() y DrinkWater() originales en la clase Cup:
prueba de clase pública{ public static void main(String[] args) { Cup aCup; BrokenCup aBrokenCup = new BrokenCup(); aCup = aBrokenCup; upcast aCup.addWater(10); void addWater(int w) { this.water = this.water + w } public void beberAgua(int w) { this.water = this.water - w; } private int water = 0;} class BrokenCup extiende Cup{ public void addWater(int w) { System.out.println("mierda, vaso roto"); public void DrinkWater(int w) { System.out. println("om...num..., no hay agua dentro"); }}
Resultados de ejecución del programa:
mierda, taza rota
Como puede ver arriba, sin instrucciones explícitas, asignamos la referencia de clase derivada aBrokenCup a su referencia de clase base aCup. Java realizará la conversión de tipos automáticamente.
Luego llamamos al método addWater() de aCup (que declaramos que es de tipo Cup). Aunque aCup es una referencia de tipo Cup, en realidad llama al método addWater() de BrokenCup. En otras palabras, incluso si aflojamos el tipo de referencia a su clase base mediante upcast, Java aún puede identificar correctamente el tipo del objeto en sí y llamar al método correcto. Java puede identificar el verdadero tipo de un objeto según la situación actual. Esto se llama polimorfismo. El polimorfismo es un aspecto importante de la orientación a objetos.
El polimorfismo es un mecanismo compatible con Java y también es un concepto importante orientado a objetos. Esto plantea una cuestión taxonómica sobre si los objetos de la subclase en realidad "son" objetos de la clase principal. Por ejemplo, un pájaro también es un animal; un coche también debe ser un medio de transporte. Java nos dice que un objeto de clase derivada se puede utilizar como objeto de clase base y Java manejará esta situación correctamente.
Por ejemplo, la siguiente relación de herencia:
Podemos decir que bebemos agua de una taza. De hecho, el significado específico de la acción del agua potable cambiará mucho en la clase derivada. Por ejemplo, beber agua con una pajita y beber agua de un vaso roto son muy diferentes, aunque todos hablamos de "beber agua" en abstracto. Por supuesto, podemos programar por separado para cada clase derivada y llamar a diferentes métodos de DrinkWater. Sin embargo, como programadores, podemos programar una taza y llamar al método DrinkWater() de Cup, independientemente de qué tipo de taza derivada sea la taza. Java llamará al método correcto correspondiente, como podemos ver en el programa anterior.
Mirando un ejemplo más significativo, agregamos un método bebida() a la clase Humano. Este método recibe un objeto taza y un número entero como parámetros. Los números enteros representan la cantidad de agua a beber:
prueba de clase pública{ public static void main(String[] args) { Invitado humano = new HumanCup hisCup = new BrokenCup(); , int w) { aCup.drinkWater(w }}
Resultados de ejecución del programa:
Mierda, no hay agua dentro.
En la definición de bebida() de la clase Humano, requerimos que el primer parámetro sea una referencia de tipo Taza. Pero en la aplicación real (clase de prueba), se utiliza el objeto de clase derivado de Cup BrokenCup. En realidad, esto convierte su Copa a la clase Copa y la pasa al método bebida(). En el método, llamamos al método DrinkWater(). Java descubrió que este objeto era en realidad un objeto BrokenCup, por lo que llamó al método correspondiente de BrokenCup.
alicaído
Podemos convertir una referencia de clase base a una referencia de clase derivada, pero el objeto al que apunta la referencia de clase base ya es el objeto de clase derivada que se va a convertir. Por ejemplo, la hisCup anterior se puede transformar hacia arriba en una referencia de clase de Copa y luego hacia abajo en una referencia de clase de BrokenCup.
tipo de objeto
En Java, todas las clases en realidad tienen un ancestro de herencia común, que es la clase Objeto. La clase Object proporciona algunos métodos, como toString(). Podemos anular estos métodos en nuestra propia definición de clase.
Objeto: antepasado
Podemos escribir un programa que opere objetos Object y pasar cualquier objeto al programa a través de upcast.
Profundizaré en la clase Objeto más adelante.
(La implementación del polimorfismo depende del soporte RTTI. Entraré en más detalles más adelante).
Resumir
Conversión de tipo básico
polimorfismo
alicaído
Objeto