<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                ### [構造器調用順序](https://lingcoder.gitee.io/onjava8/#/book/09-Polymorphism?id=%e6%9e%84%e9%80%a0%e5%99%a8%e8%b0%83%e7%94%a8%e9%a1%ba%e5%ba%8f) 在“初始化和清理”和“復用”兩章中已經簡單地介紹過構造器的調用順序,但那時還沒有介紹多態。 在派生類的構造過程中總會調用基類的構造器。初始化會自動按繼承層次結構上移,因此每個基類的構造器都會被調用到。這么做是有意義的,因為構造器有著特殊的任務:檢查對象是否被正確地構造。由于屬性通常聲明為**private**,你必須假定派生類只能訪問自己的成員而不能訪問基類的成員。只有基類的構造器擁有恰當的知識和權限來初始化自身的元素。因此,必須得調用所有構造器;否則就不能構造完整的對象。這就是為什么編譯器會強制調用每個派生類中的構造器的原因。如果在派生類的構造器主體中沒有顯式地調用基類構造器,編譯器就會默默地調用無參構造器。如果沒有無參構造器,編譯器就會報錯(當類中不含構造器時,編譯器會自動合成一個無參構造器)。 下面的例子展示了組合、繼承和多態在構建順序上的作用: ~~~ // polymorphism/Sandwich.java // Order of constructor calls // {java polymorphism.Sandwich} package polymorphism; class Meal { Meal() { System.out.println("Meal()"); } } class Bread { Bread() { System.out.println("Bread()"); } } class Cheese { Cheese() { System.out.println("Cheese()"); } } class Lettuce { Lettuce() { System.out.println("Lettuce()"); } } class Lunch extends Meal { Lunch() { System.out.println("Lunch()"); } } class PortableLunch extends Lunch { PortableLunch() { System.out.println("PortableLunch()"); } } public class Sandwich extends PortableLunch { private Bread b = new Bread(); private Cheese c = new Cheese(); private Lettuce l = new Lettuce(); public Sandwich() { System.out.println("Sandwich()"); } public static void main(String[] args) { new Sandwich(); } } ~~~ 輸出: ~~~ Meal() Lunch() PortableLunch() Bread() Cheese() Lettuce() Sandwich() ~~~ 這個例子用其他類創建了一個復雜的類。每個類都在構造器中聲明自己。重要的類是**Sandwich**,它反映了三層繼承(如果算上**Object**的話,就是四層),包含了三個成員對象。 從創建**Sandwich**對象的輸出中可以看出對象的構造器調用順序如下: 1. 基類構造器被調用。這個步驟被遞歸地重復,這樣一來類層次的頂級父類會被最先構造,然后是它的派生類,以此類推,直到最底層的派生類。 2. 按聲明順序初始化成員。 3. 調用派生類構造器的方法體。 構造器的調用順序很重要。當使用繼承時,就已經知道了基類的一切,并可以訪問基類中任意**public**和**protected**的成員。這意味著在派生類中可以假定所有的基類成員都是有效的。在一個標準方法中,構造動作已經發生過,對象其他部分的所有成員都已經創建好。 在構造器中必須確保所有的成員都已經構建完。唯一能保證這點的方法就是首先調用基類的構造器。接著,在派生類的構造器中,所有你可以訪問的基類成員都已經初始化。另一個在構造器中能知道所有成員都是有效的理由是:無論何時有可能的話,你應該在所有成員對象(通過組合將對象置于類中)定義處初始化它們(例如,例子中的**b**、**c**和**l**)。如果遵循這條實踐,就可以幫助確保所有的基類成員和當前對象的成員對象都已經初始化。 不幸的是,這不能處理所有情況,在下一節會看到。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看