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


          網站導航:
           
          主站蜘蛛池模板: 罗山县| 赞皇县| 揭东县| 萍乡市| 桂阳县| 武邑县| 始兴县| 中宁县| 德安县| 淅川县| 纳雍县| 河间市| 宜州市| 高要市| 城固县| 宝兴县| 北碚区| 田林县| 双牌县| 佳木斯市| 上杭县| 鄂伦春自治旗| 屯昌县| 常州市| 抚顺市| 德昌县| 绩溪县| 泾源县| 屏南县| 从江县| 五寨县| 贵港市| 佛学| 民县| 会东县| 台北县| 恭城| 临城县| 怀仁县| 长宁区| 武义县|