Conversión ascendente y descendente de objetos Java

El proceso de coaccionar un tipo a otro se llama conversión de tipo . La conversión de tipo de objeto mencionada en esta sección se refiere a objetos con relaciones de herencia, no a objetos de ningún tipo. Cuando se realiza una conversión de tipo en un objeto que no tiene una relación de herencia, se lanzará una   excepción de conversión de tipo Java (java.lang.ClassCastException).

Supongamos que la clase A es la clase principal de la clase B. Cuando se crea un objeto con una subclase y la referencia de este objeto se coloca en el objeto de la clase principal, por ejemplo:

A  a;
a = new B();
或
A a;
B  b = new B();
a = b;

 Objeto de transformación superior

En este momento, se dice que el objeto a es el objeto de transformación superior del objeto b .

1 . El objeto de transformación superior no puede operar las nuevas variables miembro de la subclase (perdiendo esta parte de los atributos); no puede llamar a los nuevos métodos de la subclase (perdiendo algunas funciones).

2 . El objeto de transformación superior puede acceder a las variables miembro heredadas u ocultas por la subclase, y también puede llamar al método heredado por la subclase o al método de anulación de la subclase. El objeto de transformación superior opera el método heredado por la subclase o el método reemplazado por la subclase, que es equivalente a llamar a estos métodos por el objeto de subclase . Por lo tanto, si la subclase reescribe un método de la clase principal, cuando el objeto de transformación superior del objeto llama a este método, debe llamar al método reescrito por la subclase.

① No confunda los objetos creados por la clase principal con los objetos mejorados de los objetos de la subclase.

②El objeto de transformación superior del objeto se puede forzar a convertirse en un objeto de subclase. En este momento, el objeto de subclase tiene todos los atributos y funciones de la subclase.

③No es posible asignar la referencia del objeto creado por la clase padre al objeto declarado por la subclase 

class Anthropoid 
{
	double m = 12.58;
	void crySpeak(String s){
		System.out.println(s);
	}
}
class People extends Anthropoid
{
	char m = 'A';
	int n = 60;
	void computer(int a, int b){
		int c = a + b;
		System.out.println(a + "加" + b + "等于" + c);
	}
	void crySpeak(String s){
		System.out.println(super.m + "**" + s + "**" + m);
	}
}

 

class Example5_9 
{
	public static void main(String[] args) 
	{
		People people = new People();
		Anthropoid monkey = people;   //monkey是people的上转型对象
		monkey.crySpeak("I LOVE THIS GAME");  //等同于people调用重写的crySPeak方法
		//monkey.n = 100;   非法,n是子类新增的成员变量
		//monkey.computer(12,19);   非法,子类新增的方法
		System.out.println(monkey.m);  //操作隐藏的m,不等同于people.m
		System.out.println(people.m);  //操作子类的m
		//把上转型对象强制转换为子类对象
		People zhang = (People)monkey;
		zhang.computer(55, 33);
		zhang.m = 'Z';
		System.out.println(zhang.m);
	}
}

public class Animal {
    public String name = "Animal:动物";
    public static String staticName = "Animal:可爱的动物";

    public void eat() {
        System.out.println("Animal:吃饭");
    }

    public static void staticEat() {
        System.out.println("Animal:动物在吃饭");
    }
}
public class Cat extends Animal {
    public String name = "Cat:猫";
    public String str = "Cat:可爱的小猫";
    public static String staticName = "Dog:我是喵星人";

    public void eat() {
        System.out.println("Cat:吃饭");
    }

    public static void staticEat() {
        System.out.println("Cat:猫在吃饭");
    }

    public void eatMethod() {
        System.out.println("Cat:猫喜欢吃鱼");
    }

    public static void main(String[] args) {
        Animal animal = new Cat();
        Cat cat = (Cat) animal; // 向下转型
        System.out.println(animal.name); // 输出Animal类的name变量
        System.out.println(animal.staticName); // 输出Animal类的staticName变量
        animal.eat(); // 输出Cat类的eat()方法
        animal.staticEat(); // 输出Animal类的staticEat()方法
        System.out.println(cat.str); // 调用Cat类的str变量
        cat.eatMethod(); // 调用Cat类的eatMethod()方法
    }
}

Al acceder a las propiedades y métodos del objeto referenciado a través de variables de tipo de referencia, la máquina virtual Java adoptará las siguientes reglas de vinculación:

  • El método de instancia está vinculado al método del objeto al que realmente hace referencia la variable de referencia. Este vínculo es un vínculo dinámico porque está determinado dinámicamente por la máquina virtual Java en tiempo de ejecución. Por ejemplo, animal.eat () vincula el método eat () a la clase Cat.
  • El método estático está vinculado al método del tipo declarado por la variable de referencia. Este tipo de vinculación pertenece a la vinculación estática porque la vinculación ya se realizó durante la fase de compilación. Por ejemplo, animal.staticEat () vincula el método staticEat () a la clase Animal.
  • Las variables miembro (incluidas las variables estáticas y las variables de instancia) están vinculadas a las variables miembro del tipo declarado por la variable de referencia. Esta vinculación pertenece a la vinculación estática porque la vinculación ya se realizó durante la fase de compilación. Por ejemplo, animal.name y animal.staticName están vinculados a la clase Animal.

Forzar conversión de tipo de objeto

El compilador de Java permite la conversión de tipos entre clases con herencia directa o indirecta. Para la fundición descendente, se debe realizar la conversión de tipo obligatoria; para la fundición ascendente, la conversión de tipo forzada no es necesaria.

Por ejemplo, para una variable de un tipo de referencia, el compilador de Java la maneja de acuerdo con el tipo declarado. Si usa animal para llamar a los métodos str y eatMethod (), se producirá un error, como sigue:

animal.str = "";    // 编译出错,提示Animal类中没有str属性
animal.eatMethod();    // 编译出错,提示Animal类中没有eatMethod()方法

Si desea acceder a los miembros de la clase Cat, debe pasar una conversión de tipo, de la siguiente manera:

((Cat)animal).str = "";    // 编译成功
((Cat)animal).eatMethod();    // 编译成功

Transmita el tipo de objeto Animal al tipo de objeto Cat, luego las dos oraciones anteriores se compilan correctamente. Para las siguientes declaraciones, debido al uso de la conversión de tipo forzada, también se compilará correctamente, por ejemplo:

Cat cat = (Cat)animal;    // 编译成功,将Animal对象类型强制转换为Cat对象类型

Cuando la coerción de tipo quiere ejecutarse correctamente, debe asegurarse de que el objeto al que apunta la referencia de la clase principal debe ser el objeto de la subclase. Es mejor usar el operador instanceof para juzgar y luego forzar la conversión, por ejemplo:

Animal animal = new Cat();
if (animal instanceof Cat) {
    Cat cat = (Cat) animal; // 向下转型
    ...
}

 

 

Supongo que te gusta

Origin blog.csdn.net/qq_43629083/article/details/108690133
Recomendado
Clasificación