Java类的继承覆盖问题——一段简单的代码95%的人都预计不到正确的结果

今天想着写出一段代码,关于Java类的继承覆盖问题的,运行结果和我想的不一样。

先上代码:

public class 继承覆盖的问题 extends 父类{
    public int a=10;
    @Override
    public void 打印() {
        System.out.println("调用了子类方法:"+a);
    }
    public 继承覆盖的问题(){
        //super();//这里有没有反斜杠都一样。
        super.打印();
        打印();
    }
    public static void main(String[] args) {
        继承覆盖的问题 b=new 继承覆盖的问题();
        b.打印();
        父类 c=new 父类();
        c.打印();
    }
}
class 父类{
    public int a=20;
    public 父类(){
        this.打印();
        打印();
        System.out.println("父类的a="+a);
    }
    public void 打印() {
        System.out.println("调用了父类方法:"+a);
    }
}

读者您也不妨推测一下,再在电脑上run一下,看看结果和您预想的是否一致。我估计至少95%的人预计的和实际的结果都不一致。

 

 

下面公布一下答案,当然你也可以在自己电脑上运行验证一下,这里注明一下我的jdk版本是1.8_191。

调用了子类方法:0
调用了子类方法:0
父类的a=20
调用了父类方法:20
调用了子类方法:10
调用了子类方法:10
调用了父类方法:20
调用了父类方法:20
父类的a=20
调用了父类方法:20

结果很多人没想到吧?

为什么会是这样的结果,我们可以这样理解:

(几个重要的地方说明一下)

子类为什么会出现a=0的情况,可以这样理解,int a=10这句可以分两步:int a和a=10,类在编译的时候先声明了有哪些变量和方法,是什么类型的,但并没有初始化它们。然后直接从子类跳到了父类那里。运行的流程可以用debug逐步调试来看。

子类构造方法有个//super(),有没有这个“//”结果是一致的,没有这句电脑也会默认在构造方法第一行加上这句。

到父类以后,为什么 this.打印() 和 打印() 两句执行的都是子类的 打印() 方法呢?我们可以这样理解:

我以前以为执行了super()之后是new了一个父类对象,在子类被叫做super,现在看来不是这么简单。

我们知道继承就是子类把父类的非private和final变量和方法复制下来,然后同名的会被覆盖。这里执行了super()以后不光是new了一个父类对象,也把父类的非private和final变量和方法复制到子类来,然后同名的会被覆盖。

所以这里的this是指子类对象, this.打印() 和 打印() 调用的都是子类方法,因为父类的方法被覆盖了。同理,父类的int a=20已经执行过了,为什么打印的时候a=0而非20,因为父类的a被子类的a覆盖了。但是注意了,

System.out.println("父类的a="+a);

这句,a调用的是父类的a(a=20),因为之前是调用的子类方法,子类方法里调用的自然是子类的a,这里在父类对象中调用的a当然是指父类对象的a了。

搞清楚这些问题,后面就轻松了。

super.打印();

调用的还是父类的方法。而

父类 c=new 父类();
c.打印();

两句还是和正常想的一样运行,执行的都是父类里面的东西。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值