在开始说明之前,我们直接来看一个代码

public class play {public static void main(String[] args) {Base base = new Sub();Sub sub = (Sub)base;System.out.println(base.num);System.out.println(sub.num);}
}class Base{int num = 1;public Base(){this.print();num = 2;}public void print(){System.out.println("Base.num " + num);}
}class Sub extends Base{int num = 3;public Sub(){this.print();num = 4;}public void print(){System.out.println("Sub.num " + num);}
}

在查看答案之前不妨自己先想一想输出是什么。。。。
输出:

Sub.num 0
Sub.num 3
2
4

那么答案为什么是这个呢?这就是本节我要说的内容,首先最简单的,我们知道在子类的构造器之前会自动添加super()来调用父类的构造器。有了这个基础,我们再讨论接下来的内容。


首先在执行

Base base = new Sub();

的时候,我们知道要去调用子类的构造器,那么我们来到

    public Sub(){this.print();num = 4;}

由于自动添加了super(),所以我们来到

    public Base(){this.print();num = 2;}

在我们执行this.print();之前Base类的num会先进行初始化,那么在父类中的num就等于1接下来执行this.print()的是时候,发现子类重写了print()方法,所以去调用了Base的print()方法,这个时候子类的num为默认初始值0,也就是说还没有初始化为3(顺便一说,成员变量可以不用程序员显式初始化就使用,但是局部变量是需要初始化再使用的),也就解释了这一句输出:

Sub.num 0

接下来回到Base(),执行num = 2;父类的num值为2;到这里为止super()算是执行完了,接下来回到Sub();注意这个时候执行了int num = 3;对子类的num进行了初始化,所以在执行this.print()的时候,输出的是:

Sub.num 3

而后执行的是num = 4;子类的num变为4;到目前为止,我们的:

Base base = new Sub();

算是执行完了;接下来的

System.out.println(base.num);
System.out.println(sub.num);

就不太好理解了,实际上之前说的父类num和子类num到底是什么呢?他们在java虚拟机中的什么地方呢?那么有一点java基础的朋友都知道,成员变量随对象的创建在堆中分配空间(顺带一提:局部变量在java虚拟机栈中分配空间),我们创建了Sub对象,那么sub对象中的num,肯定就是在分配给sub对象的堆中了。那么父类的num在哪呢?我查阅了一些网上的资料,发现有这么一句话:

https://www.cnblogs.com/zhaideyou/p/5844155.html
无论父类中的成员变量是否被子类覆盖,子类都会拥有父类中的这些成员变量。

那么我就猜测,父类的num也是在sub对象分配的堆中存在,是的,一个堆空间中有两个num,但是他们是属于不同类的,我们依旧可以分辨出来,我们变量的静态类型,在这里是:

Base base = new Sub(); //base静态类型为Base
Sub sub = (Sub)base; //sub静态类型为Sub

我们依照变量的静态类型来访问num,是父类的num,还是子类的num。那么输出是2,4也就不奇怪了。
另外关于成员变量的初始化,我们可以这样理解

    public Sub(){super();成员变量初始化;this.print();num = 4;}

最后给出一个初始化的顺序:

父类的静态成员初始化 -> 父类的静态代码块 -> 子类的静态成员初始化 -> 子类的静态代码块 ->
父类的代码块 -> 父类的构造方法 -> 子类的代码块 -> 子类的构造方法 另外:静态成员的初始化和静态代码块只有在类加载的时候执行一次,再次创建实例对象的时候,不再执行了

以上就是对整个题目的理解了,困于为java初学者,以上只作为参考建议;

更新:
证实的确在子类的对象堆中会为父类无论是方法,还是域都会分配空间,无论父类的这些部分对子类是否可见。你可以将父类和子类修改为:

class Base{int num = 1;private int num2 = 10;public Base(){this.print();num = 2;num2 = 11;}public void print(){System.out.println("Base.num " + num);}public void print2(){System.out.println("Base.num2 " + num2);}
}class Sub extends Base{int num = 3;public Sub(){this.print();num = 4;}public void print(){super.print2();System.out.println("Sub.num " + num);}
}

预期输出:

Base.num2 10
Sub.num 0
Base.num2 11
Sub.num 3
2
4

查看输出的确如此,读者可以自己分析一下。

java中子类和父类的初始化和函数调用关系相关推荐

  1. python中子类调用父类的初始化方法

    http://bestchenwu.iteye.com/blog/1044848 http://www.crazyant.net/1303.html 一直不太理解python的初始化方法,今天找了下资 ...

  2. 关于JAVA中子类和父类的构造方法

    本篇文章总结了一些关于Java构造方法的常见问题. 为什么创建了一个子类对象会调用其父类的构造方法 如下代码示例: package simplejava;class Super {String s;p ...

  3. java中子类继承父类时是否继承构造函数

    java继承中对构造函数是不继承的,只是调用(隐式或显式). 以下是例子: public class FatherClass { public FatherClass() {        Syste ...

  4. java中子类继承父类程序执行顺序问题

    为什么80%的码农都做不了架构师?>>>    Java中,new一个类的对象,类里面的静态代码块.非静态代码.无参构造方法.有参构造方法.类的一般方法等部分,它们的执行顺序相对来说 ...

  5. java中子类与父类中隐含的this引用的分析

    /*看一下下面的程序,看是否你的答案和运行的答案是否一致! */ class Parent{public int x;public Parent p;public Parent(){}public P ...

  6. Java中子类覆盖父类方法所必须满足的条件

    因为太喜欢,所以转来,侵删! 参考自:http://www.it165.net/pro/html/201504/39284.html 一.描述 子类重写(覆盖)父类的方法必须满足的条件: 1.父类中的 ...

  7. java中子类与父类强制转换_java中父类强制转换成子类的错觉

    引言:父类引用指向子类对象在java中十分常见,比如: Object object=new a();//a是一个类名 但是有时候我们看见子类引用指向了父类对象,就是上边的反过来,比如 图片中圈1标识的 ...

  8. java中子类对父类中的私有变量和私有方法有拥有权无使用权

    解释的我觉得也到位:子类拥对父类的私有变量具有拥有权 但是不具有使用权. 再和以前学的东西联系起来,总结如下: 1.不管父类中的成员变量是静态的还是非静态的,子类统统拥有(这里不用继承概念). 2.不 ...

  9. 关于Java中子类调用父类方法

    当一个类继承于另一个类,子类中没有父类的方法时.用子类的对象调用方法时,会首先在子类中查找,如果子类中没有改方法,再到父类中查找. 当一个方法只在父类中定义时,调用该方法时会使用父类中的属性.  如果 ...

最新文章

  1. 193. 一个不错的日历插件
  2. python基础教程:可变,不可变数据类型
  3. Python打造一款多线程端口扫描器
  4. mcse 2000 认证介绍
  5. c++判断奇偶_第十一届(今年)蓝桥杯省模拟赛 试题+源码 C/C++详解
  6. go语言结构体标签的意义
  7. Installshield关于.NET安装时需要重启动的处理办法,以及延伸出的重启后继续安装的安装包的一点想法...
  8. 串口接收到的字符型数据如何转化成数字
  9. 【SQL 数据库】将一张数据表信息复制到另一张数据表
  10. windows环境中JDK环境变量配置
  11. 大厂用的分库分表方案和demo源码,都在这里了!
  12. 超级终端连接华为交换机_win8系统使用超级终端连接华为交换机的操作方法
  13. ant design table样式修改合集
  14. Centos下查看和修改网卡Mac地址
  15. linux系统新增2t以上硬盘,在linux下新增一块硬盘的操作。(包含大于2T的硬盘在linux下挂载操作)...
  16. Dreammaker水疗流行的Eclipse从他们的加州系列,审议
  17. 90后迎来30岁,比升职更重要的是这8件事
  18. 生则决定生,去则实不去
  19. 判断两个数运算是否越界
  20. 基于 React hooks + Typescript + Cesium 场景暗角效果

热门文章

  1. BC#29A:GTY's math problem(math) B:GTY's birthday gift(矩阵快速幂)
  2. 拖动无标题栏的窗体,需要处理的三个事件
  3. 如何解决Bluetooth系统设计的棘手问题
  4. 基于xp系统搭建android开发环境
  5. Ubuntu18常用指令集合(更新中)
  6. java B2B2C 源码多租户电子商城系统-Spring Cloud组件详解...
  7. 算法踩坑6-二叉搜索树排序
  8. Rhino脚本引擎技术介绍
  9. HTTP长连接、短连接
  10. 【Python学习系列二十八】绘图库pyecharts