目录
首先了解转型的定义:
1、向上转型:父类 父类引用 = new 子类(天然发生的)
2、向下转型:子类 子类引用 = (子类)父类;(强制类型转换)
- // 定义动物基类
- public class Animal extends Object {
-
- public void move() {
- System.out.println("动物在移动");
- }
- }
-
-
- // 定义Cat类
- public class Cat extends Animal {
-
- //重写父类中继承的方法
- public void move() {
- System.out.println("猫在走猫步");
- }
- public void catchMouse() {
- System.out.println("猫抓老鼠");
- }
- }
-
- // 定义Bird类
- public class Bird extends Animal {
-
- public void move() {
- System.out.println("鸟儿在飞翔");
- }
-
- public void fly() {
- System.out.println("Bird fly");
- }
- }
- public class Test01 {
-
- public static void main(String[] args) {
-
- Animal a2 = new Cat(); // 天然发生的向上转型,猫一定是动物,但动物不一定是猫
- a2.move();
- c2.catchMouse();
- }
- }
如果对象调用的方法是父类中没有的,(比如调用catMouse方法),会报错。因此此处就需要用到强制类型转换(向下转型)。
- public class Test {
-
- public static void main(String[] args) {
-
- Animal a2 = new Cat();//向上转型
- a2.move();
- Cat c2 = (Cat) a2;//向下转型:将Animal类型的a2转换为Cat类型的c2
- c2.catchMouse();
- }
- }
如果测试程序这样写:
- public class Test {
-
- public static void main(String[] args) {
-
- Animal a3 = new Bird();
- Cat c3 = (Cat) a3;
- }
- }
上述代码在编译阶段不会报错,但在运行阶段会报错,为什么呢?
问题分析:
①首先,编译通过,因为编译器检测到a3的数据类型是Animal,因为Animal和Cat之间存在继承关系,且Animal是父类,Cat是子类,父类转换成子类,向下转型语法合格。
②程序虽然编译通过了,但是程序在运行阶段会抛出异常,因为JVM堆内存中真实存在的对象是Bird类型,Bird类型对象无法转换成Cat类型对象,因为二者不存在继承关系。
如果测试代码这样写:
- public class Test {
-
- public static void main(String[] args) {
-
- //子类指向父类
- Animal a4 = new Animal();
- Cat c4 = (Cat) a4;
- }
- }
上述代码同样编译不报错,但运行阶段会报错,为什么?
问题分析:
①首先,编译通过说明转型的语法是不存在问题的。
②编译通过,但程序抛出异常,因为a4是Animal类型的对象,而c4指向的是子类对象Cat,子类对象不能指向父类对象。
我们实操发现:进行向下转型时会遇到各种运行时异常情况,此时我们引入了关键字 instanceof(摘帽子,脱掉帽子看看究竟是哪种类型)
- public class Test {
-
- public static void main(String[] args) {
-
- //解决方式:
- Animal a3 = new Bird();
- if(a3 instanceof Cat) {
- Cat c3 = (Cat) a3;
- c3.catchMouse();
- } else if(a3 instanceof Bird) {
- Bird b2 = (Bird)a3;
- b2.fly();
- }
- }
- }
①只有有继承关系的类型之间才能进行类型转换;
②向上转型是天然发生的,但只能访问和调用到来自于父类的属性和行为;
③子类的引用不能指向父类或其他子类对象。
④把父类引用赋给子类引用,语法上必须使用强制类型转换,要想运行成功还必须保证父类引用指向的对象一定是该子类对象(最好使用instance判断后,再强转)