千禧城MOPLAY官方网址千禧城MOPLAY官方网址

MOPLAY登录
MOPLAY千禧城官网

详解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()

 

分析一下

BigEgg2Egg2的子类,他们都有Yolk的内部类,而且BigEgg2.Yolk继承了Egg2.Yolk。注意此处,同名类可以继承。

那么,他们构造方法为什么不能覆盖,都是Public Yolk(){}。

当然,网上都说子类继承父类除构造方法以外的所有方法,但这是结果,我要知道为什么!!

 

先说几个错误的观点

1.

有说构造方法的方法名与类名必须一样,父子类不能同名,故不能继,所以不能覆盖构造方法。

这个不用多说,这个例子,就是大神写出来打这样说的人的脸的。

 

2.

有说因为子类继承父类的时候,先运行父类构造函数;具体的说就是运行父类时就会先“调用”父类的构造函数,注意“调用”和继承不是一个含义,实质上是“自动运行”。

这个强行用中文语法来解释的,达到中文6级了啊。

 

3.

有说构造方法不是成员函数,故不能继承,所以谈不上覆盖。

这个真的有道理,是java官方文档上的。大多数人找到这里估计就满足了。

但是,跟太阳从东方升起西方落下那样,我想知道为甚么这么设计啊啊啊啊啊啊!!!!!

 

4.

正确答案

(1).构造器代表这个类本身,在创建之时申请内存。

(2).子类创建的时候,会默认调用父类的默认构造方法-,若修改了必须显示调用。(这就是为什么创建子类先创建父类的原因了)

 

那么很明显了,要是同名类之间可以覆盖了,子类创建时就是创建了两个自己而没有父类。

Java设计的时候,他们绝对想到有些人会像强迫症那样折腾个同名类继承,然后实现构造覆盖的场景吧....

 

总结

构造方法是唯一的,不能又造爸爸又造儿子

欢迎阅读本文章: 张崇海

千禧城MOPLAY客服

MOPLAY登录