详解Java构造方法为什么不能覆盖,我的钻牛角尖病又犯了....
一
看Think in Java,遇到个程序
class Egg2 {
protected class Yolk {
public Yolk() {
System.out.println("Egg2.Yolk()");
} public void f() {
System.out.println("Egg2.Yolk.f()");
}
} private Yolk y = new Yolk(); public Egg2() {
System.out.println("New Egg2()");
} public void insertYolk(Yolk yy) {
y = yy;
} public void g() {
y.f();
}
} public class BigEgg2 extends Egg2 {
public class Yolk extends Egg2.Yolk {
public Yolk() {
System.out.println("BigEgg2.Yolk()");
} public void f() {
System.out.println("BigEgg2.Yolk.f()");
}
} public BigEgg2() {
insertYolk(new Yolk());
} public static void main(String[] args) {
// Egg2 e1 = null;
// Egg2 e2 = new BigEgg2();
// new Egg2();
new BigEgg2();
// e2.g();
}
} ///:~
输出
Egg2.Yolk()
New Egg2()
Egg2.Yolk()
BigEgg2.Yolk()
二
其实基本上我根据后面的几个注释,也大概明白了看的顺序构造顺序是什么,见图
构造顺序图
三
但是,看了输出,我就纳闷为什么,为什么第三行不是BigEgg2.Yolk(),不能覆盖吗?
Egg2.Yolk()
New Egg2()
Egg2.Yolk()
BigEgg2.Yolk()
四
分析一下
BigEgg2是Egg2的子类,他们都有Yolk的内部类,而且BigEgg2.Yolk继承了Egg2.Yolk。注意此处,同名类可以继承。
那么,他们构造方法为什么不能覆盖,都是Public Yolk(){}。
当然,网上都说子类继承父类除构造方法以外的所有方法,但这是结果,我要知道为什么!!
五
先说几个错误的观点
1.
有说构造方法的方法名与类名必须一样,父子类不能同名,故不能继,所以不能覆盖构造方法。
这个不用多说,这个例子,就是大神写出来打这样说的人的脸的。
2.
有说因为子类继承父类的时候,先运行父类构造函数;具体的说就是运行父类时就会先“调用”父类的构造函数,注意“调用”和继承不是一个含义,实质上是“自动运行”。
这个强行用中文语法来解释的,达到中文6级了啊。
3.
有说构造方法不是成员函数,故不能继承,所以谈不上覆盖。
这个真的有道理,是java官方文档上的。大多数人找到这里估计就满足了。
但是,跟太阳从东方升起西方落下那样,我想知道为甚么这么设计啊啊啊啊啊啊!!!!!
4.
正确答案
(1).构造器代表这个类本身,在创建之时申请内存。
(2).子类创建的时候,会默认在构造方法的第一行调用父类的默认构造方法-,若修改了必须显示调用。(这就是为什么创建子类时先创建完父类的原因了)
那么很明显了,要是同名类之间可以覆盖了,子类创建时就是创建了两个自己而没有父类。
Java设计的时候,他们绝对想到有些人会像强迫症那样折腾个同名类继承,然后实现构造覆盖的场景吧....
总结
构造方法是唯一的,不能又造爸爸又造儿子
最新文章
- Java程序设计之Constructor
- Caffe学习系列(8):solver及其配置
- C# 刷票程序
- 使用EA逆向生成数据库E-R图
- ExtJs gridPanel Column 时间格式化
- poj1064 二分,注意精度!
- MVC模块化架构
- Android---Parcelable包装类的作用
- Vijos1144小胖守皇宫【树形DP】
- Mysql--七种 Join 查询
- python 之路,200行Python代码写了个打飞机游戏!
- Leetcode Articles: Insert into a Cyclic Sorted List
- vue 路由参数
- [20181219]script使用小技巧.txt
- RMQ 字符串 F. Strings and Queries
- vue2.0 vs vue
- Flask初级(二)为flash创建路由,访问路径。
- 并发工具类(二)同步屏障CyclicBarrier
- date.getTime()
- Redis Quick Start [遇到问题解决问题版]
热门文章
- CodeForces-329C(div1):Graph Reconstruction(随机&;构造)
- HihoCoder1656 : 前缀后缀查询([Offer收割]编程练习赛39)(字典树+小技巧)
- sangfor-AF 地址转换以及各种模式理解(路由,透明,虚拟网线,混合模式)
- ACM学习历程——HDU4472 Count(数学递推) (12年长春区域赛)
- bzoj 2865 字符串识别 —— 后缀数组
- 利用正则表达式类解析SQL语句,达到Worklist兼容各个RIS数据库的目的
- C#的Unit Test如何根据exception来判断函数是否执行正确
- 前端PHP Session的实例
- 1.4 DVWA亲测文件上传漏洞
- 交互原型设计软件axure rp学习之路(二)