🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
### 向上转型与向下转型 > 向上转型:将子类转型为父类; > 向下转型:将父类转型为子类; ![](https://img.kancloud.cn/91/f7/91f753722b51f445021b9c5b25c28470_728x478.png) #### 向上转型的 **特点** - 语法 ``` <父类型> <引用变量名> = new <子类型>(); ``` - 好处:隐藏了子类型,提高了代码的扩展性; - 坏处:只能使用父类的功能,不能使用子类的特有功能,功能被限定; - 场景:使用父类的功能即可完成的操作,不需要面对子类类型; ```java /** * 向上转型的缺点 */ public class Car { /** * 开车 */ public void run() { System.out.println("父类的run()"); } } /** * 蔚来 */ class Nio extends Car { @Override public void run() { System.out.println("子类的run()"); } /** * 汽车的价格 */ public void price() { System.out.println("子类汽车的价格"); } public static void main(String[] args) { // 习惯 Nio nio = new Nio(); nio.run(); nio.price(); System.out.print("\n"); // 向上转型 Car car = new Nio(); car.run(); // car.price(); } } ``` 运行程序后输出的内容:![](https://img.kancloud.cn/44/38/4438f6876e7ff2604f6406e91f4a995c_294x190.png) > 使用car实例调用price的时候,提示`Cannot resolve method 'price' in 'Car'` - 代码中*Car car = new Nio()*,我们使用了向上转型,但是由于进行了向上转型,就失去了使用父类中所没有的方法的“权利”,不能调用price()方法; - 那向上转型到底有什么用呢? ```java /** * 向上转型的优点 */ public class Car { /** * 开车 */ public void run() { System.out.println("父类的run()"); } public void tune(Car car) { // 插钥匙,拧钥匙,开火,踩离合,加油门,松离合,起步走 car.run(); } } class Tesla extends Car{ @Override public void run() { System.out.println("Tesla的run()"); } /** * 汽车的价格 */ public void price() { System.out.println("Tesla汽车的价格"); } } /** * 蔚来 */ class Nio extends Car { @Override public void run() { System.out.println("Nio的run()"); } /** * 汽车的价格 */ public void price() { System.out.println("Nio汽车的价格"); } public static void main(String[] args) { // 向上转型缺点 - 不能使用子类扩展的price功能 Car car = new Nio(); car.run(); // car.price(); System.out.print("\n"); // 习惯 Nio nio = new Nio(); nio.run(); nio.price(); System.out.print("\n"); // 向上转型的优点 car.tune(nio); Tesla tesla = new Tesla(); // 方便扩展 car.tune(tesla); } } ``` ##### 向上转型总结 向上转型虽然使代码变得简洁,体现了JAVA的抽象编程思想,但是也出现了上面提到的子类无法调用其独有的方法,这要怎么解决呢?所以就有了与之对应的向下转型,弥补了向上转型所带来的缺陷。 #### 向下转型 #### 向上转型的 **特点** - 语法 ``` <父类型> <引用变量名A> = new <子类型>(); <子类型> <引用变量名> = (子类型)<引用变量名A>; ``` - 好处:可以使用子类型的特有功能; - 坏处:向下转型具有风险,容易发生ClassCastException,只要转换类型和对象不匹配就会发生。可以使用关键字instanceof进行解决; - 场景:泛型类业务; ```java public class Car { /** * 开车 */ public void run() { System.out.println("父类的run()"); } } class Tesla extends Car { @Override public void run() { System.out.println("Tesla的run()"); } /** * 汽车的价格 */ public void price() { System.out.println("Tesla汽车的价格"); } } class Nio extends Car { @Override public void run() { System.out.println("Nio的run()"); } /** * 汽车的价格 */ public void price() { System.out.println("Nio汽车的价格"); } public static void main(String[] args) { // 先向上转型 Car[] car = { new Nio(), new Tesla() }; car[0].run(); // car[0].price(); // 后向下转型 Nio nio = (Nio)car[0]; nio.price(); // 后向下转型 Tesla tesla = (Tesla) car[1]; tesla.price(); // 不向上转型 Car car2 = new Car(); ((Nio)car2).run(); } } ``` > 如果不先进行`向上转型`,直接实例化Car,进行强制性`向下转型`可以不? ![](https://img.kancloud.cn/1d/24/1d24d16ff0c4d7b561ba49f1c24b6ba8_414x182.png) 编译使未报错,但运行后程序出现错误; ![](https://img.kancloud.cn/17/e5/17e5ff28f08f8e91218f92497c30e141_1900x138.png) ***** 这是因为我们实例化了一个父类对象,当我们使用强制转型转为`Nio`时,由于子类可以定义自己的方法,父类的域小于子类的域,这个时候我们直接向下转型就会发生这个错误,所以需要*先向上转型,后向下转型*。 ##### **instanceof**关键字 - 语法 ``` # 一个对象是否为一个类的实例 **对象名 instanceof 类名** ``` ![](https://img.kancloud.cn/dd/8e/dd8e01ef5d37255a6fb8c980bb33bad8_770x218.png) ***** ### 参考与引用 [CSDN - 迷棱](https://blog.csdn.net/guchenjun789/article/details/81055317) [CSDN - yddcc](https://blog.csdn.net/weixin_40601536/article/details/84103029) [CSDN - TNTZS666](https://blog.csdn.net/TNTZS666/article/details/80274526)