Java向上、向下转型的作用
一、向上转型
这个是我们平时用的最多的,比如我们要定义某一个方法的时候,经常使用一个抽象类(父类)或者接口作为参数把他们的子类传递过去,在传递的过程中,这个子类默认就是进行向上转型的。下面通过三个类来描述这个转型的变化。
// 父类
public class Father {
public void method(){
System.out.println("这是父类的方法");
}
}
// 子类
public class Son extends Father {
@Override
public void method(){
System.out.println("这是子类的方法");
}
// 注意这个儿子特有的方法
public void sonMethod(){
System.out.println("这是子类特有的方法");
}
}
// 子类
public class Girl extends Father {
public void method(){
System.out.println("这是女儿的方法");
}
}
当我们使用下面的代码调用对应的方法method(),这个时候默认是进行了向上转型的。
public class Main {
public static void main(String[] args) {
Father son = new Son();
Father girl = new Girl();
son.method();
girl.method();
}
}
//运行结果:
// 这是子类的方法
// 这是子类的方法
我们可以简单的理解为,我们声明了一个引用son,但前面的Father让jvm认为这是一个指向Father类的引用,所以这个引用只是记录了Father里面有的方法,当我们调用这个method()方法时,引用真正指向的是一个Son对象,所以实际执行的是Son方法。但是因为这个引用记录的父类里面没有子类的方法,所以当我们想访问子类的方法时,就会报错。
基于上面的这个理解,我们可以在父类中声明一个他特有的方法:
public class Father {
public void method(){
System.out.println("这是父类的方法");
}
public void methodFather(){
System.out.println("这是父类特有的方法");
}
}
之后我们在对向上转型的引用调用父类的这个方法:
public class Main {
public static void main(String[] args) {
Father son = new Son();
son.methodFather();
}
}
//运行结果:
// 这是父类特有的方法
如此,我们可以得出结论(多态的实质):当一个父类引用指向一个子类对象的时候,它会默认的进行向上转型,这个引用调用某个方法的时候,首先会检查这个引用(父类)有没有这个方法,没有的话直接报错;有的话看对应的子类对象有没有重写了这个方法,有则执行子类的方法,没有则执行父类的方法。
二、向下转型
针对向上转型带来的一个问题——向上转型的引用无法访问子类的特有方法,这个时候便用到了我们的向下转型。对上面的主函数的代码做下面对的改变,便可以访问到子类对象特有的方法:
public class Main {
public static void main(String[] args) {
Father son = new Son();
((Son) son).sonMethod();
}
}
//运行结果:
// 这是子类特有的方法
注意这里的“向下”指的是声明的引用类型(比如上面的son是Father)与强制向下转换的类型(上面是Son)一个父与子的关系。