向上转型
向上转型发生在父类对于子类的引用中:
现有父类Animal:
abstract class Animal {
String name;
int age;
// 抽象类不能实例化,但是构造函数存在的意义是能够让子类 初始化父类的成员
public Animal(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Animal{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
和子类Cat:
class Cat extends Animal{
public Cat(String name, int age) {
super(name, age);
}
// 子类特有的方法,猫吃猫粮,所有动物不一定都吃猫粮
public void eat() {
System.out.println("cat eat()");
}
public void bark() {
System.out.println("cat bark()");
}
@Override
public String toString() {
return "Cat{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
在主方法中这样调用:
public class Main {
public static void main(String[] args) {
Animal animal = new Cat("猫",12);
System.out.println(animal);
}
}
结果:
Cat{name='猫', age=12}
可见虽然animal是一个Animal类型的引用,但是因为其是对于子类Cat的引用,所以调用了子类的toString(),发生了向上转型。
注意:
需要注意的是虽然此时的animal调用的方法是子类重写的方法,
但是转型后的父类对象仍然不能访问子类对象特有的方法。
向上转型的方式:
1.父类直接引用子类
2.通过实参是子类,形参是父类的方式
3.通过一个父类类型的引用接受返回值是子类的方法
向下转型
与向上转型相对,向下转型是由子类转向父类。可以解决转型父类不能调用子类特有方法。
实现方式:
注意
向下转型必须是在向上转型之后才能进行。
也就是说,子类先转成父类,然后再转为子类的过程叫做向下转型。
Animal animal = new Cat("猫",12);
// 只能调用父类自己的方法:
animal.bark();
animal = (Cat)animal;
((Cat) animal).eat();
// 或者:
Cat cat = (Cat)animal;
cat.eat();
结果:
cat bark()
cat eat()
cat eat()
但不能像这样:
Cat cat = new Animal("猫",12);
或者这样:
Animal animal = new Animal("猫",12);
Cat cat = (Cat) animal;
异常:
Exception in thread "main" java.lang.ClassCastException:
Animal cannot be cast to Cat
只有先向上转型后才能发生向下转型。
总结
向上转型是小转大
向下转型是小转大再转小