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 閱讀(295) 評論(0)  編輯  收藏 所屬分類: OOP
          2007-02-18 22:08:25
          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          主站蜘蛛池模板: 哈密市| 永济市| 沧州市| 浦江县| 天长市| 潞城市| 民勤县| 彩票| 上林县| 台湾省| 柳河县| 长兴县| 伽师县| 铜川市| 寻甸| 衡阳县| 澄江县| 靖州| 石台县| 宣武区| 和硕县| 普安县| 台州市| 固原市| 吉木乃县| 江达县| 白玉县| 凌海市| 苏州市| 彭州市| 固始县| 麦盖提县| 谷城县| 云南省| 溆浦县| 湾仔区| 秭归县| 闻喜县| 滨海县| 甘谷县| 巍山|