向上转型
继承中我们谈到继承是is-a的相互关系,例如猫继承与动物,
所以我们可以说猫是动物,或者说猫是动物的一种。这样将
猫看做动物就是向上转型。将子类转换成父类,在继承关系
上是向上移动的,所以一般称之为向上转型。由于向上转型
是从一个叫特殊类向普通类转换,所以它总是安全的,唯一
发生变化的可能就是属性和方法的丢失。例如正方形是特殊
的长方形,我们可以说一个正方形就是是一个长方形。这就
是为什么编译器在“未曾明确表示转型”或“未曾指定特殊标记”的情况下,仍然允许向上转型的原因。
向上转型发生的时机
1、直接赋值
Animal animal = new Bird("圆圆");
即父类引用引用子类对象
2、方法传参
public class Test {
public static void main(String[] args) {
Bird bird = new Bird("圆圆");
feed(bird); //feed方法的参数是animal(父类),
//这里传了一个bird(子类)
}
//feed方法的参数为animal类型
public static void feed(Animal animal) {
}
}
3、方法返回
public class Test {
public static void main(String[] args) {
Animal animal = findMyAnimal();
}
//findMyAnimal方法的返回值类型为Animal (父类)
public static Animal findMyAnimal() {
Bird bird = new Bird("圆圆");
return bird; //返回bird(子类)
}
}
向上转型后,只能访问和使用父类的方法和属性,而不能访问和使用子类的方法和属性
向下转型
向上转型是子类对象转成父类对象, 向下转型就是父类对象
转成子类对象. 即子类引用引用父类对象。相比于向上转型
来说, 向下转型没那么常见,但是也有一定的用途,
为了让向下转型更安全, 我们可以先判定一下父类的 本质
是不是一个 子类 实例,是的话 再来转换,否则会出现编译
错误。
举个通俗的例子:
比如人类,人可以分为医生,老师等类,即人类是医生类的
父类。现由于疫情期间需要大量医生,我们就需要大量医生,
这时就需要拉好多人去当医生,即父类对象(人)转为子类
对象(医生)。但这需要有个前提,就是你这个人之前要
当过医生,否则将一个没当过医生的人去充当医生,那后果
是很严重的。而对于向下转型,就是这个父类引用要是
原本子类的一个对象,即向上转型,(相当于当过医生的
人),而如何判断这个人当过医生没,我们用instanceof 判
断,如果当过,返回真,否则返回假。即instanceof 可以判
定一个引用是否是某个类的实例. 如果是,则返回 true. 这时
再进行向下转型就比较安全了.
Animal animal = new Cat("小猫");
//animal引用的是Cat对象,所以可以向下转为Cat,而
//Bird则不行
if (animal instanceof Bird) {
Bird bird = (Bird)animal;
bird.fly();
}
if (animal instanceof Cat) {
Cat cat = (Cat)animal;
}