一、向上转型

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 指向 Doganimal = 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

三、向上转型与向下转型

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐