Java 类型转换:为什么”向上转型“很安全,”向下转型“却可能摔得很惨?
一、向上转型
part1 概念
向上转型:实际上就是创建一个子类对象,将其当作父类对象来使用。
part2 语法格式
语法格式:父类类型 对象名 = new 子类类型( )
Animal animal = new Dog( );
part3 使用场景
1、直接赋值



2、方法传参





【注意】
①向上转型和方法调用的关系
向上转型是指将子类对象赋值给父类引用,比如 Dog 和 Cat 是 Animal 的子类,Dog dog = new Dog(); 创建了一个 Dog 子类对象,Animal animal = dog; 就是向上转型,此时 animal 这个父类引用可以调用父类中定义的方法, 如果子类重写了父类方法,那么会遵循多态原则,调用子类重写后的方法 。
在代码里,eatFood(Animal animal) 方法接收一个 Animal 类型的参数,当传入 Dog 或者 Cat 子类对象时,就发生了向上转型,然后调用 animal.eat() 方法,这利用了多态机制,执行的是子类重写后的 eat 方法。也就是说,向上转型的情况下,实例方法同样可以实现多态调用,并不要求方法一定是 static 修饰的。
②声明为 static 的原因
静态方法的特性:静态方法属于类本身, 可以直接通过类名调用,不需要创建类的实例。当把 eatFood 声明为 static 时,意味着它可以在不创建 Main 类实例的情况下被调用,比如在其他类中可以直接使用 Main.eatFood(someAnimalInstance); 来调用这个方法,提供了一种方便的工具方法调用方式。
3、方法返回值


【解析】
(1)在 Java 中,equals() 方法主要用于比较两个对象的内容是否相等(与 == 运算符不同,== 用于比较对象的引用是否指向同一内存地址)。
(2)代码里 if ("狗".equals(ret)) 和 else if ("猫".equals(ret)) 是在比较字符串内容:
①当传入的参数 ret 的值是字符串 "狗" 时,"狗".equals(ret) 返回 true,同时方法会创建并返回 Dog 对象。
②当传入的参数 ret 的值是字符串 "猫" 时,"猫".equals(ret) 返回 true,同时方法会创建并返回 Cat 对象。
③如果 ret 是其他值,方法返回 null。
part4 向上转型的优缺点
1、向上转型的优点
让代码实现更简单灵活。
2、向上转型的缺点
不可以调用子类特有的方法。
二、向下转型
part1 概念
将一个子类对象经过向上转型之后当作父类对象使用,再也不可以调用子类特有的方法。但有的时候可能需要调用子类特有的方法。
此时:将父类对象再次还原为子类对象即可,即向下转型。
part2 语法格式
向下转型的格式:子类对象 = (子类类型)父类对象;
cat = (Cat)animal;
part3 使用场景
【代码】




【执行结果】

part4 为什么不安全?


向下转型用的比较少,而且不安全,万一转换失败,运行就会抛出异常。
part5 如何提高向下转型的安全性
Java中为了向下转型提高安全性,引入了 instanceof ,如果该表达式为 true ,则可以安全转换。

【解析】如何知道向下转型转的是dog,而不是cat?
1. 看变量的 “实际引用对象”
在 Java 中,一个父类引用(如 Animal animal)可以指向子类对象(Cat 或 Dog)。向下转型时,必须确保父类引用实际指向的是目标子类的对象,否则会抛出 ClassCastException(类型转换异常)。
在上述代码中:
// 步骤1:animal 先指向 Cat 对象
Animal animal = cat;
// 步骤2:然后 animal 被赋值为指向 Dog 对象
animal = dog;
因此,当执行 dog = (Dog)animal; 时,animal 实际指向的是 Dog 对象,所以可以安全地向下转型为 Dog。
2. 看代码的逻辑意图
代码的编写是有逻辑顺序的:
①先让 animal 指向 Cat,并进行了 Cat 相关的操作(虽然代码里没写,但从后续转型看是铺垫)。
②然后让 animal 指向 Dog(animal = dog;),后续的向下转型 (Dog)animal 就是为了操作 Dog 特有的方法(如 bark())。
如果想转 Cat,需要保证 animal 实际指向 Cat 对象,例如:
animal = cat; // 让 animal 重新指向 Cat 对象
Cat cat2 = (Cat)animal; // 此时可以安全转 Cat
3. 总结:如何判断?
①核心原则:父类引用 animal 实际指向的是哪个子类对象,就可以向下转型为哪个子类。
②代码证据:在 dog = (Dog)animal; 之前,有 animal = dog; 这行代码,明确让 animal 指向了 Dog 对象,因此能转 Dog。
三、向上转型与向下转型

更多推荐


所有评论(0)