目录
1、转型语法
首先了解转型的定义:
1、向上转型:父类 父类引用 = new 子类(天然发生的)
2、向下转型:子类 子类引用 = (子类)父类;(强制类型转换)
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");
}
}
3、向上转型
public class Test01 {
public static void main(String[] args) {
Animal a2 = new Cat(); // 天然发生的向上转型,猫一定是动物,但动物不一定是猫
a2.move();
c2.catchMouse();
}
}
4、向下转型
4.1 问题1:
如果对象调用的方法是父类中没有的,(比如调用catMouse方法),会报错。因此此处就需要用到强制类型转换(向下转型)。
4.2 向下转型:
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();
}
}
4.3 问题2:
如果测试程序这样写:
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类型对象,因为二者不存在继承关系。
4.4 问题3:
如果测试代码这样写:
public class Test {
public static void main(String[] args) {
//子类指向父类
Animal a4 = new Animal();
Cat c4 = (Cat) a4;
}
}
上述代码同样编译不报错,但运行阶段会报错,为什么?
问题分析:
①首先,编译通过说明转型的语法是不存在问题的。
②编译通过,但程序抛出异常,因为a4是Animal类型的对象,而c4指向的是子类对象Cat,子类对象不能指向父类对象。
5、向下转型问题的解决办法
我们实操发现:进行向下转型时会遇到各种运行时异常情况,此时我们引入了关键字 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();
}
}
}
6、总结
①只有有继承关系的类型之间才能进行类型转换;
②向上转型是天然发生的,但只能访问和调用到来自于父类的属性和行为;
③子类的引用不能指向父类或其他子类对象。
④把父类引用赋给子类引用,语法上必须使用强制类型转换,要想运行成功还必须保证父类引用指向的对象一定是该子类对象(最好使用instance判断后,再强转)