java中子类和父类的初始化和函数调用关系
在开始说明之前,我们直接来看一个代码
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中子类和父类的初始化和函数调用关系相关推荐
- python中子类调用父类的初始化方法
http://bestchenwu.iteye.com/blog/1044848 http://www.crazyant.net/1303.html 一直不太理解python的初始化方法,今天找了下资 ...
- 关于JAVA中子类和父类的构造方法
本篇文章总结了一些关于Java构造方法的常见问题. 为什么创建了一个子类对象会调用其父类的构造方法 如下代码示例: package simplejava;class Super {String s;p ...
- java中子类继承父类时是否继承构造函数
java继承中对构造函数是不继承的,只是调用(隐式或显式). 以下是例子: public class FatherClass { public FatherClass() { Syste ...
- java中子类继承父类程序执行顺序问题
为什么80%的码农都做不了架构师?>>> Java中,new一个类的对象,类里面的静态代码块.非静态代码.无参构造方法.有参构造方法.类的一般方法等部分,它们的执行顺序相对来说 ...
- java中子类与父类中隐含的this引用的分析
/*看一下下面的程序,看是否你的答案和运行的答案是否一致! */ class Parent{public int x;public Parent p;public Parent(){}public P ...
- Java中子类覆盖父类方法所必须满足的条件
因为太喜欢,所以转来,侵删! 参考自:http://www.it165.net/pro/html/201504/39284.html 一.描述 子类重写(覆盖)父类的方法必须满足的条件: 1.父类中的 ...
- java中子类与父类强制转换_java中父类强制转换成子类的错觉
引言:父类引用指向子类对象在java中十分常见,比如: Object object=new a();//a是一个类名 但是有时候我们看见子类引用指向了父类对象,就是上边的反过来,比如 图片中圈1标识的 ...
- java中子类对父类中的私有变量和私有方法有拥有权无使用权
解释的我觉得也到位:子类拥对父类的私有变量具有拥有权 但是不具有使用权. 再和以前学的东西联系起来,总结如下: 1.不管父类中的成员变量是静态的还是非静态的,子类统统拥有(这里不用继承概念). 2.不 ...
- 关于Java中子类调用父类方法
当一个类继承于另一个类,子类中没有父类的方法时.用子类的对象调用方法时,会首先在子类中查找,如果子类中没有改方法,再到父类中查找. 当一个方法只在父类中定义时,调用该方法时会使用父类中的属性. 如果 ...
最新文章
- 193. 一个不错的日历插件
- python基础教程:可变,不可变数据类型
- Python打造一款多线程端口扫描器
- mcse 2000 认证介绍
- c++判断奇偶_第十一届(今年)蓝桥杯省模拟赛 试题+源码 C/C++详解
- go语言结构体标签的意义
- Installshield关于.NET安装时需要重启动的处理办法,以及延伸出的重启后继续安装的安装包的一点想法...
- 串口接收到的字符型数据如何转化成数字
- 【SQL 数据库】将一张数据表信息复制到另一张数据表
- windows环境中JDK环境变量配置
- 大厂用的分库分表方案和demo源码,都在这里了!
- 超级终端连接华为交换机_win8系统使用超级终端连接华为交换机的操作方法
- ant design table样式修改合集
- Centos下查看和修改网卡Mac地址
- linux系统新增2t以上硬盘,在linux下新增一块硬盘的操作。(包含大于2T的硬盘在linux下挂载操作)...
- Dreammaker水疗流行的Eclipse从他们的加州系列,审议
- 90后迎来30岁,比升职更重要的是这8件事
- 生则决定生,去则实不去
- 判断两个数运算是否越界
- 基于 React hooks + Typescript + Cesium 场景暗角效果
热门文章
- BC#29A:GTY's math problem(math) B:GTY's birthday gift(矩阵快速幂)
- 拖动无标题栏的窗体,需要处理的三个事件
- 如何解决Bluetooth系统设计的棘手问题
- 基于xp系统搭建android开发环境
- Ubuntu18常用指令集合(更新中)
- java B2B2C 源码多租户电子商城系统-Spring Cloud组件详解...
- 算法踩坑6-二叉搜索树排序
- Rhino脚本引擎技术介绍
- HTTP长连接、短连接
- 【Python学习系列二十八】绘图库pyecharts