<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>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                # 6.7 向上轉換 繼承最值得注意的地方就是它沒有為新類提供方法。繼承是對新類和基類之間的關系的一種表達。可這樣總結該關系:“新類屬于現有類的一種類型”。 這種表達并不僅僅是對繼承的一種形象化解釋,繼承是直接由語言提供支持的。作為一個例子,大家可考慮一個名為`Instrument`的基類,它用于表示樂器;另一個派生類叫作`Wind`。由于繼承意味著基類的所有方法亦可在派生出來的類中使用,所以我們發給基類的任何消息亦可發給派生類。若`Instrument`類有一個`play()`方法,則`Wind`設備也會有這個方法。這意味著我們能肯定地認為一個`Wind`對象也是`Instrument`的一種類型。下面這個例子揭示出編譯器如何提供對這一概念的支持: ``` //: Wind.java // Inheritance & upcasting import java.util.*; class Instrument { public void play() {} static void tune(Instrument i) { // ... i.play(); } } // Wind objects are instruments // because they have the same interface: class Wind extends Instrument { public static void main(String[] args) { Wind flute = new Wind(); Instrument.tune(flute); // Upcasting } } ///:~ ``` 這個例子中最有趣的無疑是`tune()`方法,它能接受一個`Instrument`引用。但在`Wind.main()`中,`tune()`方法是通過為其賦予一個`Wind`引用來調用的。由于Java對類型檢查特別嚴格,所以大家可能會感到很奇怪,為什么接收一種類型的方法也能接收另一種類型呢?但是,我們一定要認識到一個`Wind`對象也是一個`Instrument`對象。而且對于不在`Wind`中的一個`Instrument`(樂器),沒有方法可以由`tune()`調用。在`tune()`中,代碼適用于`Instrument`以及從`Instrument`派生出來的任何東西。在這里,我們將從一個`Wind`引用轉換成一個`Instrument`引用的行為叫作“向上轉換”。 ## 6.7.1 何謂“向上轉換”? 之所以叫作這個名字,除了有一定的歷史原因外,也是由于在傳統意義上,類繼承圖的畫法是根位于最頂部,再逐漸向下擴展(當然,可根據自己的習慣用任何方法描繪這種圖)。因素,`Wind.java`的繼承圖就象下面這個樣子: 由于轉換的方向是從派生類到基類,箭頭朝上,所以通常把它叫作“向上轉換”,即`Upcasting`。向上轉換肯定是安全的,因為我們是從一個更特殊的類型到一個更常規的類型。換言之,派生類是基類的一個超集。它可以包含比基類更多的方法,但它至少包含了基類的方法。進行向上轉換的時候,類接口可能出現的唯一一個問題是它可能丟失方法,而不是贏得這些方法。這便是在沒有任何明確的轉換或者其他特殊標注的情況下,編譯器為什么允許向上轉換的原因所在。 也可以執行向下轉換,但這時會面臨第11章要詳細講述的一種困境。 (1) 再論組合與繼承 在面向對象的程序設計中,創建和使用代碼最可能采取的一種做法是:將數據和方法統一封裝到一個類里,并且使用那個類的對象。有些時候,需通過“組合”技術用現成的類來構造新類。而繼承是最少見的一種做法。因此,盡管繼承在學習OOP的過程中得到了大量的強調,但并不意味著應該盡可能地到處使用它。相反,使用它時要特別慎重。只有在清楚知道繼承在所有方法中最有效的前提下,才可考慮它。為判斷自己到底應該選用組合還是繼承,一個最簡單的辦法就是考慮是否需要從新類向上轉換回基類。若必須上溯,就需要繼承。但如果不需要向上轉換,就應提醒自己防止繼承的濫用。在下一章里(多態性),會向大家介紹必須進行向上轉換的一種場合。但只要記住經常問自己“我真的需要向上轉換嗎”,對于組合還是繼承的選擇就不應該是個太大的問題。
                  <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>

                              哎呀哎呀视频在线观看