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

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                # 7.1 向上轉換 在第6章,大家已知道可將一個對象作為它自己的類型使用,或者作為它的基類型的一個對象使用。取得一個對象引用,并將其作為基類型引用使用的行為就叫作“向上轉換”——因為繼承樹的畫法是基類位于最上方。 但這樣做也會遇到一個問題,如下例所示(若執行這個程序遇到麻煩,請參考第3章的3.1.2小節“賦值”): ``` //: Music.java // Inheritance & upcasting package c07; class Note { private int value; private Note(int val) { value = val; } public static final Note middleC = new Note(0), cSharp = new Note(1), cFlat = new Note(2); } // Etc. class Instrument { public void play(Note n) { System.out.println("Instrument.play()"); } } // Wind objects are instruments // because they have the same interface: class Wind extends Instrument { // Redefine interface method: public void play(Note n) { System.out.println("Wind.play()"); } } public class Music { public static void tune(Instrument i) { // ... i.play(Note.middleC); } public static void main(String[] args) { Wind flute = new Wind(); tune(flute); // Upcasting } } ///:~ ``` 其中,方法`Music.tune()`接收一個`Instrument`引用,同時也接收從`Instrument`派生出來的所有東西。當一個`Wind`引用傳遞給`tune()`的時候,就會出現這種情況。此時沒有轉換的必要。這樣做是可以接受的;`Instrument`里的接口必須存在于`Wind`中,因為`Wind`是從`Instrument`里繼承得到的。從`Wind`向`Instrument`的向上轉換可能“縮小”那個接口,但不可能把它變得比`Instrument`的完整接口還要小。 ## 7.1.1 為什么要向上轉換 這個程序看起來也許顯得有些奇怪。為什么所有人都應該有意忘記一個對象的類型呢?進行向上轉換時,就可能產生這方面的疑惑。而且如果讓`tune()`簡單地取得一個`Wind`引用,將其作為自己的參數使用,似乎會更加簡單、直觀得多。但要注意:假如那樣做,就需為系統內`Instrument`的每種類型寫一個全新的`tune()`。假設按照前面的推論,加入`Stringed`(弦樂)和`Brass`(銅管)這兩種`Instrument`(樂器): ``` //: Music2.java // Overloading instead of upcasting class Note2 { private int value; private Note2(int val) { value = val; } public static final Note2 middleC = new Note2(0), cSharp = new Note2(1), cFlat = new Note2(2); } // Etc. class Instrument2 { public void play(Note2 n) { System.out.println("Instrument2.play()"); } } class Wind2 extends Instrument2 { public void play(Note2 n) { System.out.println("Wind2.play()"); } } class Stringed2 extends Instrument2 { public void play(Note2 n) { System.out.println("Stringed2.play()"); } } class Brass2 extends Instrument2 { public void play(Note2 n) { System.out.println("Brass2.play()"); } } public class Music2 { public static void tune(Wind2 i) { i.play(Note2.middleC); } public static void tune(Stringed2 i) { i.play(Note2.middleC); } public static void tune(Brass2 i) { i.play(Note2.middleC); } public static void main(String[] args) { Wind2 flute = new Wind2(); Stringed2 violin = new Stringed2(); Brass2 frenchHorn = new Brass2(); tune(flute); // No upcasting tune(violin); tune(frenchHorn); } } ///:~ ``` 這樣做當然行得通,但卻存在一個極大的弊端:必須為每種新增的`Instrument2`類編寫與類緊密相關的方法。這意味著第一次就要求多得多的編程量。以后,假如想添加一個象`tune()`那樣的新方法或者為`Instrument`添加一個新類型,仍然需要進行大量編碼工作。此外,即使忘記對自己的某個方法進行重載設置,編譯器也不會提示任何錯誤。這樣一來,類型的整個操作過程就顯得極難管理,有失控的危險。 但假如只寫一個方法,將基類作為參數使用,而不是使用那些特定的派生類,豈不是會簡單得多?也就是說,如果我們能不顧派生類,只讓自己的代碼與基類打交道,那么省下的工作量將是難以估計的。 這正是“多態性”大顯身手的地方。然而,大多數程序員(特別是有程序化編程背景的)對于多態性的工作原理仍然顯得有些生疏。
                  <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>

                              哎呀哎呀视频在线观看