【Java基础】怎么理解父类引用能指向子类对象?

我们可以从对象的内存角度来理解试试:

假设现在有一个父类Father,假设Father类里面的变量占内存2M,有一个它的子类SonSon里面的变量占用内存1M

Father f = new Father();//系统分配2M内存
Son s = new Son();//系统分配3M内存(2M+1M)

这里可能你会有疑问了,Son的变量不是只占1M内存吗?为什么系统给上面的s分配了3M内存?因为子类中有一个隐藏的引用super会指向父类实例,所以在实例化子类之前会先实例化一个父类,也就是说会先执行父类的构造方法,由于s中包含了父类的实例,所以s可以调用父类的方法。

下面我们来看一下代码:

public class Main {
    public static void main(String[] args) {
        Father f = new Son();
        f.fun1();
    }
}

class Father {
    public void fatherFun(){
        System.out.println("fatherFun");
    }

    public void fun1(){
        System.out.println("fatherFun1");
    }
}

class Son extends Father {
    public void childFun(){
        System.out.println("childFun");
    }

    public void fun1(){
        System.out.println("childFun2");
    }
}

执行Father f = new Son();语句为向上转型。假设Father类里面的变量占内存2M,有一个它的子类SonSon里面的变量占用内存1M。这时候f会指向那3M内存中的2M,就是说,f只是指向了子类实例中的父类实例对象。所以f只能调用父类的方法(存储在2M内存中),而不能调用子类的方法(存储在1M内存中)。

main方法中,执行f.fun1();语句。控制台会打印子类中重写父类的fun1()方法中的内容"childFun2"

main方法中,执行f.fatherFun();语句。控制台会打印父类中的fatherFun()方法中的内容"fatherFun"

main方法中,执行f.childFun();语句。会报编译错误,因为childFun方法是子类有而父类没有的,f不能调用。父类引用只能调用子类实例中重写父类的方法

发布了17 篇原创文章 · 获赞 19 · 访问量 501

猜你喜欢

转载自blog.csdn.net/qq_42745749/article/details/104691512