Java -- 父类和子类拥有同名变量

39 篇文章 1 订阅
Java – 父类和子类拥有同名变量

                      请仔细观察系列两段程序的不同之处:一个Son类重写print方法,另一个则没有重写。

分析该问题必须从字节码的角度入手,否则根本不可能看清事情的本质。

成员变量(非静态的)的赋值过程:

  1. 默认初始化
  2. 显示初始化 / 代码块中初始化
  3. 构造器中初始化
  4. 有了对象之后。可以“对象.属性”或“对象.方法”的方式队成员变量进行赋值。

                                    最重要的是要搞清楚父类和子类的同名变量是否占用一块内存!!!

方法存在重载,但属性不存在重载。
package test0;

/**
 * @author wsh2096
 * @create 2020-10-28 8:57
 */
public class SonTest {
    public static void main(String[] args) {
        Father f = new Son();
        System.out.println(f.x);
    }
}

class Father {

    int x = 10;

    public Father() {
        this.print();
        x = 20;
    }

    public void print() {
        System.out.println("Father.x = " + x);
    }
}

class Son extends Father {

    int x = 30;

    public Son() {
        this.print();
        x = 40;
    }

    @Override
    public void print() {
        System.out.println("Son.x = " + x);
    }
}

在这里插入图片描述
Father类的字节码:
       init方法字节码:
在这里插入图片描述
       print方法字节码
在这里插入图片描述

Son类的字节码:
       init方法字节码:
在这里插入图片描述
       print方法字节码
在这里插入图片描述

分析:
        第一个输出0的原因是:在调用print方法的时候,子类Son重载该方法,所以调用子类方法进行输出,此时子类的x还没有显示初始化,所以输出的是子类x默认初始化值0。

        第二个输出30的原因是:在Son类的构造器进行输出,此时Son类的x已经进行完显示初始化,将Son的x值赋值为30.

        第三个输出20的原因是:此时变量f实际上指向的是Son类的实例,但是外观上是Father类,由于方法存在重载,会进行动态链接进行查找子类的具体实现方法!但是,属性十不存在重载,也就不存在动态链接,所以此时输出f的x值,是去查找Father类实例的属性x的值。(此时父类的构造器已经执行完毕,所以此时的值为20.)


                                                               对父类的print方法不进行重载!

package test0;

/**
 * @author wsh2096
 * @create 2020-10-28 8:57
 */
public class SonTest {
    public static void main(String[] args) {
        Father f = new Son();
        System.out.println(f.x);
    }
}

class Father {

    int x = 10;

    public Father() {
        this.print();
        x = 20;
    }

    public void print() {
        System.out.println("Father.x = " + x);
    }
}

class Son extends Father {

    int x = 30;

    public Son() {
        this.print();
        x = 40;
    }

//    @Override
//    public void print() {
//        System.out.println("Son.x = " + x);
//    }
}

在这里插入图片描述
       这个没有重载print方法的版本就不放字节码了,与重载的版本相比,只不过是少了东西,其他部分都是一样的。


       最后一个输出不需要解释!
       第一个输出10,是因为子类并没有重载print方法,所以调用Father的print方法,输出的就是父类的x值,此时已经完成显示初始化,为10.
       第二个输出20,属性不能重载,输出Father的x值,此时完成Father构造器初始化,将值赋为20.

  • 11
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值