莊周夢蝶

          生活、程序、未來
             :: 首頁 ::  ::  :: 聚合  :: 管理

          ruby實現抽象類和抽象方法

          Posted on 2007-02-06 13:07 dennis 閱讀(1453) 評論(1)  編輯  收藏 所屬分類: 動態語言
          ruby語言本身并沒有提供abstract class和abstract method機制。這是ruby的spirit所決定的。但如果我們真的需要定義一個公共抽象類(或者抽象方法)來讓子類來實現,又該如何做呢?
          ??? 我們可以通過在調用方法時拋出NotImplementedError來防止方法被調用。如(來自《ruby cookbook》的例子):

          ?class?Shape2D
          ??def?area
          ????raise?NotImplementedError
          .new("#{self.class.name}#area是抽象方法")
          ??end
          end?
          class?Square?
          <?Shape2D
          ??def?initialize(
          length)
          ????
          @length?=?length
          ??end
          ??
          ??def?area
          ????
          @length?**?2
          ??end
          end


          ?? 父類
          Shape2D的方法area就是我們所需要的“抽象方法”了。你不能直接調用:

          s1=Shape2D.new
          s1
          .area

          這樣調用將拋出錯誤:Shape2D#area是抽象方法 (NotImplementedError)
          Shape2D的子類Square覆寫了此方法。由此我們模擬實現了抽象方法。那么抽象類該如何實現呢?自然而然,我們想到如果把類的initialize方法這樣處理,那么這樣的類將沒辦法被new生成,不正是我們所需要的抽象類?說干就干:

          ?class?Shape2D
          ??def?initialize
          ????raise?NotImplementedError
          .new("#{self.class.name}#area是抽象類")
          ??end
          ??def?area
          ????raise?NotImplementedError
          .new("#{self.class.name}#area是抽象方法")
          ??end
          end?


          當你調用Shape2D.new時,解釋器將提示你:Shape2D是抽象類(NotImplementedError)

          我們已經實現了抽象方法和抽象類,感覺還是不夠好,對每一個需要實現抽象類的類來說,我們都需要去寫一句:raise NotImplementedError.new...實在不夠爽。ruby鼓勵我們去修改類的行為,甚至是標準庫,那好,我們修改Class類吧,提供類似attr_reader的聲明式服務:
          class?Class
          ??def??
          ????abstract(
          *args)
          ????args
          .each?do?|method_name|
          ??????
          ??????define_method(method_name)?
          do?|*args|
          ????????
          if?method_name?==?:initialize???
          ??????????msg?
          =?"#{self.class.name}是抽象類"
          ????????
          else
          ??????????msg?
          =?"#{self.class.name}##{method_name}是抽象方法"
          ????????end
          ????????raise?NotImplementedError
          .new(msg)
          ????????
          ??????end
          ????end
          ??end
          end


          OK,如此一來,我們的Shape2D可以寫成:
          ?class?Shape2D
          ????abstract
          :initialize,:area??#initialize和area是抽象方法
          ?end


          盡管在ruby中,抽象類和抽象方法是否有用存在懷疑,不過知道這樣的辦法總是不錯的主意

          評論

          # re: ruby實現抽象類和抽象方法  回復  更多評論   

          2007-02-06 20:01 by rubycainiao
          連句柄的類型都沒有了,還要多態干什么呢?
          主站蜘蛛池模板: 循化| 年辖:市辖区| 通许县| 渭源县| 温宿县| 黑河市| 香格里拉县| 偃师市| 三都| 泗阳县| 宣城市| 九江县| 姜堰市| 安丘市| 烟台市| 孙吴县| 法库县| 无极县| 和林格尔县| 库伦旗| 前郭尔| 玉门市| 潮州市| 清徐县| 延庆县| 奉节县| 延吉市| 会宁县| 彭泽县| 元阳县| 广平县| 团风县| 报价| 通海县| 甘孜| 鸡东县| 内黄县| 大悟县| 涟源市| 康马县| 会东县|