定义父类 Animal,代码如下:
public class Animal {
public void sleep() {
System.out.println("小动物在睡觉");
}
public static void doSleep(Animal animal) {
// 此时的参数是父类对象,但是实际调用时传递的是子类对象,就是向上转型。
animal.sleep();
}
public static void main(String[] args) {
Animal animal = new Animal();
animal.doSleep(new Cat());
animal.doSleep(new Dog());
}
}
public class Cat extends Animal {
@Override
public void sleep() {
System.out.println("猫正在睡觉");
}
}
public class Dog extends Animal {
@Override
public void sleep() {
System.out.println("狗正在睡觉");
}
}
如果不用向上转型则必须写两个 doSleep 方法,一个传递 Cat 类对象,一个传递 Dog 类对象。这还是两个子类,如果有多个子类就要写很多相同的方法,造成重复。可以看出向上转型更好的体现了类的多态性,增强了程序的间接性以及提高了代码的可扩展性。当需要用到子类特有的方法时可以向下转型,这也就是为什么要向下转型。
总结如下:
- 把子类对象直接赋给父类引用是向上转型,向上转型自动转换。如 Father father = new Son();
- 指向子类对象的父类引用赋给子类引用是向下转型,要强制转换。使用向下转型,必须先向上转型,为了安全可以用 instanceof 运算符判断。 如 father 是一个指向子类对象的父类引用,把 father 赋给子类引用 son,即
Son son =(Son)father;
。其中 father 前面的(Son)
必须添加,进行强制转换。 - 向上转型不能使用子类特有的属性和方法,只能引用父类的属性和方法,但是子类重写父类的方法是有效的。
- 向上转型时会优先使用子类中重写父类的方法,如例 1 中调用的 sleep 方法。
- 向上转型的作用是减少重复代码,可以将父类作为参数,这样使代码变得简洁,也更好的体现了多态。