• 甜ོ~ 
    2019-06-20
    老师,为什么构造方法中调用重载的构造方法,必须得是在第一行,有什么特殊考虑吗

    作者回复: 我好像在视频里提过一嘴, 但是是在后面讲解super的时候. 如果不从继承关系的角度看, 让this放在第一行确实是没有硬道理的.

    后面讲到super的时候, 也就是下面两节:

    71 | super:和父类对象沟通的桥梁
    72 | super:调用父类的构造方法

    会讲到, 子类的构造方法, 会强制在第一行调用父类的构造方法. 这一点和this要在第一行有关联. 而这一点, 也正是给了构造方法调用别的构造方法, 必须是第一行给了一个强理由.

    首先说一下为什么"子类的构造方法, 会强制在第一行调用父类的构造方法", 这个我在视频里提了一嘴, (人工划重点)这是因为子类可以访问父类的方法和属性. 那么必须保证子类的对象在做任何事情之前, 子类里那个隐含的父类对象, 必须初始化完成. 否则, 初始化都没完成, 调用方法, 返回属性, 都可能得到的是不对的状态/值(人工划重点结束).

    好, 知道了这一点之后, 很自然的可以推出, this调用必须也在第一行, 否则的话, this调用里会调用父类构造方法, 如果this不是第一句, 那么也就隐含着调用父类构造方法不是第一句, 也就是说, 子类可能使用的父类的属性或者方法是没有初始化完成的.

    其实我也觉得这个挺别扭, 拿参数稍微算一下,再给构造方法不行吗? 但是这个确实很难控制, 或者说没必要做这么复杂. 是给自己挖坑. 所以干脆一刀切, super必须是第语句, this也必须是第一句.

    
     3
  • 彧豪
    2020-02-06
    萌老师,我看到了后面61课访问修饰符那里,因为示例代码把public改成了private,所以我说重新写一下示例代码,重新敲一下,然后就遇到了问题,在构造方法重载这里:
      public MerchandiseV2WithConstructor(String name, String id, int count, double soldPrice, double purchasePrice) {
        this.name = name;
        this.id = id;
        this.count = count;
        this.soldPrice = soldPrice;
        this.purchasePrice = purchasePrice;
      }

      public MerchandiseV2WithConstructor(String name, String id, int count, double soldPrice) {
        this(name, id, count, soldPrice, soldPrice * 0.8);
      }
    我把this(参数)换成了new MerchandiseV2WithConstructor(参数),然后m.describe()的时候,输出的成员变量的值都是初始值,null, null, 0.0这些,而我debug进去,构造方法是执行了的,就是this.name = name;这些语句是执行了的,也被赋值为了我传入的值,比如书桌啊,DESK9527什么的,但是接着走到describle方法中时那些值就会变回初始值null, null, 0.0这些了,我很困惑:为何构造方法重载的时候里面用this(参数)可以,而new MerchandiseV2WithConstructor(参数)就不行呢?求指点
    展开

    作者回复: new M就是创建另一个新的实例了呀。

    this()本质上是一个方法,用来初始化对象。new是一个表达式,用来创建新的实例。


    一个是创建实例,一个是初始化刚刚创建出来的实例。你品,你细细品

    
    
  • let me go
    2020-01-21
    老师,“在构造方法里才能调用重载的方法,语法为this”,这句话我不能理解,尤其是这个this,它表示的是之前写的那个带参数的构造方法吗?

    作者回复: 对的,this(参数列表),就是在构造方法里调用重载的构造方法。

    
    
我们在线,来聊聊吧