关于java的父类持有子类实例的引用

转载自:https://blog.csdn.net/qq_36515344/article/details/84679082

Father father = new Son();//正确

当Son继承于Father类时,这种情况的引用编译器是支持的,

Son son= new Father();//错误

而反之却不能。

 

这是由内存机制决定的,父类声明的引用的可见区域是父类的字段和方法,而子类声明的引用的可见区域是子类和父类中继承下来的全部字段和方法,这就造成了父类引用访问子类实例的时候是内存安全的,而子类引用访问父类实例是会导致内存问题的。

 

我们可以使用下面一段代码来验证父类引用的可视性(它只能在内存中找到父类中定义了的相关字段和方法)。

 
//test.java
public class test{
    public static void main(String[] args){
        Father father = new Son();
        father.run();
        //System.out.println(father.son);//错误,对于父类引用father来说,子类实例中的son字段是不存在的
}
//father.java
public class Father{
    int fa = 0;
    void run(){
        System.out.println("father");
    }
}
//son.java
public class Son extends Father{
    int son = 1;
    void run(){
        System.out.println("son");
    }
}

 

输出结果为son(调用的是子类中的方法)

这里为什么调用的是子类的方法呢?父类的引用调用了子类的方法

那对于相同名的字段而言会出现像方法一样的情况吗?

 
public class test{

public static void main(String[] args){

Father father = new Son();

System.out.println(father.fa);

father.run();

}



}


class Father{

int fa = 0;//相同字段

void run(){

System.out.println("father");

}

}

class Son extends Father{

int fa = 1;//相同字段

void run(){

System.out.println(super.fa);

System.out.println(fa);

System.out.println("son");

}

}

输出结果:

我们发现它调用的是父类的fa字段,那这是为什么呢?

说明继承对字段和方法的处理是不一样的,对于字段而言,是不存在重写的,如果有相同的两个字段,是会同时存在的,但是对于父类和子类的引用而言,这两个字段的可见性是不同的,而子类中的方法会重写父类中的同名方法,这时候子类实例的内存空间中是存在两个同名字段和子类重写后的方法的引用。所以,父类引用调用的方法是子类重写过后的方法。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值