zoukankan      html  css  js  c++  java
  • 详解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设计的时候,他们绝对想到有些人会像强迫症那样折腾个同名类继承,然后实现构造覆盖的场景吧....

    总结

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

  • 相关阅读:
    别让安全问题拖慢了 DevOps!
    精华阅读第 9 期 |滴滴出行 iOS 客户端架构演进之路
    微信小程序组件化开发框架WePY
    Web前端鼠标悬停实现显示与隐藏效果
    Web前端社交账号注册按钮
    微信小游戏2
    微信小游戏
    (2)
    Angular实战项目(1)
    一步HTML5教程学会体系
  • 原文地址:https://www.cnblogs.com/ydymz/p/9284255.html
Copyright © 2011-2022 走看看