1. 動態綁定
          若子類SubClass覆蓋了父類SuperClass的某個非final非private方法f1()
          即使子類被聲明為
          SuperClass child = new SubClass();
          使用child.f1()時仍然訪問子類的f1()
          2. 如果把某個方法聲明為final,可以防止其他人覆蓋該方法。更為重要的一點是,這樣做可以有效的關閉動態綁定,從而生成更有效的代碼。然而,大多數情況下,這樣做對程序的整體性能不會有什么改觀。因此并不提倡為了僅僅提高性能而使用final。
          3. private方法無法被覆蓋,但還是要注意覆蓋private方法的現象,上面的例子中,如SuperClass中含有private方法f2(),而子類中也聲明了同名的方法f2(),子類被聲明為
          SuperClass child = new SubClass();
          child.f2()時訪問了父類的f2()
          4. 構造器和多態
          構造器基本順序:
          1)調用基類構造器(遞歸過程)
          2)按聲明順序調用成員的初始化方法。
          3)調用導出類構造器的主體。
          5. 繼承與清理
          通過組合與京城方法來創建新類時,不必擔心對象的清理問題。如果確實遇到清理的問題,那么必須為新類創建dispose()方法。當覆蓋被繼承類的dispose()方法時,務必記住調用基類的dispose()方法,也要注意清理順序。
          6. 構造器內部的多態方法的行為
          如果要調用構造器內部的一個動態綁定的方法,就要用到那個方法的被覆蓋后的定義。然而,產生的效果可能相當難于預料,并且可能造成一些難于發現的隱藏錯誤。
          在任何構造器的內部,整個對象可能只是部分形成,然而一個動態綁定的方法調用卻會向外深入到繼承層次結構內部,它可以調用導出類的方法。如果在構造器里這么做,那么就可能會調用某個方法,而這個方法所操縱的成員可能還未初始化--這肯定會出問題。
          import com.bruceeckel.simpletest.*;
          abstract class Glyph {
          abstract void draw();
          Glyph() {
          System.out.println("Glyph() before draw()");
          draw();
          System.out.println("Glyph() after draw()");
          }
          }
          class RoundGlyph extends Glyph {
          private int radius = 1;
          RoundGlyph(int r) {
          radius = r;
          System.out.println(
          "RoundGlyph.RoundGlyph(), radius = " + radius);
          }
          void draw() {
          System.out.println(
          "RoundGlyph.draw(), radius = " + radius);
          }
          }
          public class PolyConstructors {
          public static void main(String[] args) {
          new RoundGlyph(5);
          }
          }
          最后顯示
          Glyph() before draw()
          RoundGlyph.draw(), radius = 0
          Glyph() after draw()
          RoundGlyph.RoundGlyph(), radius = 5
          實際應用中,或許這會導致RoundGlyph對象生成后只畫了一個點,而不是預期的半徑為1的圓。
          解釋:初始化的實際過程是:
          1)將分配給對象的儲存空間初始化為二進制的0。
          2)調用基類構造器。即此時調用了draw()方法,但radius仍然為0。
          3)按照聲明的順序調用成員的初始化方法。
          4)調用導出類的構造器主體。
          邏輯方法已經十分完美,但行為卻會出錯(這種情況下,C++會產生更合理的行為)
          因此,編寫構造器有一條有效的準則:用盡可能簡單的方法使對象進入正常狀態;如果可以的話,避免調用其他方法。在構造器內唯一能夠安全調用的那些方法是基類中的final方法(包括private方法),這些方法不能被覆蓋,也就不會出現上述問題。
          7. 依然是繼承/組合的選擇
          一條通用的準則是,用繼承表達行為間的差異,用字段表達狀態上的變化。
          8. 純繼承:只有在基類或接口中已經建立的方法才可以在導出類中被覆蓋,基類與導出類的接口相同。
          9. 向下轉型

          posts - 403, comments - 310, trackbacks - 0, articles - 7
            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

          2.18 Java notes - Polymorphism

          Posted on 2007-04-22 20:24 ZelluX 閱讀(294) 評論(0)  編輯  收藏 所屬分類: OOP
          2007-02-18 22:08:25
          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          主站蜘蛛池模板: 宾阳县| 高州市| 华安县| 阜阳市| 周至县| 子长县| 凉山| 台北县| 手游| 东乡县| 寻乌县| 金山区| 贡山| 纳雍县| 晋江市| 曲沃县| 凌云县| 井冈山市| 万载县| 布尔津县| 广宁县| 云林县| 山东省| 蓬安县| 盐山县| 郸城县| 璧山县| 女性| 拜泉县| 万安县| 胶南市| 秭归县| 新干县| 廉江市| 汉寿县| 周宁县| 沂水县| 本溪市| 新晃| 巫溪县| 山东省|