java继承深入解析

最近在进行知识回顾的时候发现很多知识只是了解了如何去使用,根据what、why、how去分析发现why(为什么)和how(怎么是)层次理解薄弱。
java的特点之一继承,大家都知道什么是继承和为什么要用继承,但是java中怎么实现的继承呢?
子类对象中会保存一个实例对象的引用super,该引用指向其父类。 在实际的方法调用时,java会先在当前类的对象中寻找名称相同的方法,如果没有,就到super引用的父类对象中去寻找该方法,所以,若在子类中存在和父类方法的签名和返回值类型完全相同的方法(重写)的话,java就会直接调用该对象的方法而不用去父类去寻找调用方法了。而且在子类对象中,可以直接通过super来调用父类对象中的方法 。
结合以上文字描述和图片能清晰的了解继承实现原理。
这里写图片描述

接下来通过代码。

public class Test {
    public static void main(String[] args) {
        B b = new B(0);
        int y = b.getY();
    }
}

class A{
    public static int x=2;
    private int y=2;
    protected int z;

    A(){
        x=x+66;
        showX();
    }

    A(int n){
        x=n+66;
        showX();
    }
    public void showX(){
        System.out.println("A.x="+x);
    }
    public int getY(){
        return y;
    }
}

class B extends A{
    B(int x){
        this.x=x+66;
        showX();
    }
    public void showX(){
        System.out.println("B.x"+x);
    }
    public int getY(){
        System.out.println("B.Y="+(super.getY()+x));
        return super.getY()+x;
    }
}

以上代码输出的结果为:
B.x68
B.x66
B.Y=68
是不是和预想的不太一样,请看以下解释:
1:B b = new B(0);实例化一个B,首先调用的是父类A的无参构造函数,此时x的值为68,之后调用A无参构造函数中的showX()方法,这里是最可能出现异议的地方,它调用的是B类的showX(),具体原因大家可以了解,本人觉得根据上图所示,虽然showX()在A类的无参构造函数中,但实际调用时还是先走B类的方法,B类没有改方法才会找父类的方法。
2:调用B类带参数的构造函数,此时this.x为68将A类的x属性继承,但是经过赋值运算,x变为66,注意A类的x和B类的x均为66,由于B类没有重写x的值,寻找过程就为find B 类的x,有就使用B类的x,没有往父类上找x,找到了此时this.x指向父类的x,修改的也是父类的x值。
3:虽然y在A类上是私有的,但B类还是能通过super.getY()方法获取y的值。

以上均为三行输出值的具体分析。
接下来还有一个代码例子:

abstract class C{
    int i=9;
    public void printI(){
        System.out.println("i="+i);
    }
}

public class D extends C{
    int i=2;
    public static void main(String[] args){
        D d = new D();
        d.printI();
    }
}

输出结果为:i=9
好像和上面讲的不太一样,不应该为i=2?
分析如下:由于D类中没有printI方法,实际调用的为父类C的printI方法,C类中的printI方法只会调用C类中的成员变量或方法中的局部变量所以输出的结果为:i=9。
jvm的执行过程
(1)子类D 的构造方法被调用,实例化一个D对象,D对象的成员被初始化
(2)jvm隐含的调用父类的构造方法,实例化一个C对象,C对象的成员被初始化。
(3)由于C对象的printI()未被屏蔽,所以调用的C对象的printI()函数。
那么,在这里A的成员函数当然是访问自己的成员变量了。
代码也可以这么写:

package com.wupeng;

class C{
    int i=9;
    public void printI(){
        System.out.println("i="+i);
    }
}

public class D extends C{
    int i=2;
    public void printI(){
        super.printI();
    }
    public static void main(String[] args){
        D d = new D();
        d.printI();
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值