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

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                # 類(Class)與模塊(Module) ### 類 我們在對象和方法那一節中,提過這個概念。 比如 「人類」。 在面向對象概念中,一個類代表一組對象共同特征的抽象集合。比如「人類」,代表了人的共同特征,可以直立行走、會說話、會思考等人類特征。 ~~~ *注:最好你可以打開irb或者是pry跟著練習* 在命令行輸入 irb 或 pry,回車,你就進入到了一個互動的Ruby Shell界面里,你可以在里面輸入代碼,并且會馬上得到運行結果。 chef-shell命令,就是基于irb來做的。 ~~~ **用Ruby代碼表示就是:** ~~~ class People def walk puts 'can' end def say puts 'hello word' end def think puts 'I got!' end end ~~~ Ruby中用class關鍵字來聲明一個類,注意類名People,是大寫字母開頭。沒錯,這個People,就是一個常量。 ~~~ person = People.new ~~~ 我們可以使用new方法來創建一個對象, 這里的person,就是我們創造的一個人。 ~~~ person.walk person.say person.think ~~~ 人類的行為, 這個person都可以做。 當你運行以上代碼之后,會發現,這些方法都返回nil,這是因為Ruby的方法,如果你沒有明確使用return,默認只返回方法內部最后一行的運行結果,上面的方法中,最后一行都是puts語句,puts語句會返回nil。 當然你可以使用return語句來給方法指定返回值。比如: ~~~ def walk return 'can' end ~~~ 但是他的名字呢,性別呢,種族或國籍等其他屬性呢?這些個體的屬性,是不可能每個人都一樣的,那么我們該怎么設定呢? ~~~ class People def initialize(name="", gender="") @name = name @gender = gender end end ~~~ 我們打開類Peopole,使用initialize 方法,來給一個類添加屬性。就是當你使用new方法創建一個對象的時候,這個對象可以被賦予屬性。 上面的代碼里, @name和@gender,都是實例變量, 而參數name,gender都是本地變量,也就是局部變量,它們可以被賦予默認值,但是,他們只能在initialize這個方法的作用域范圍內有效,所以,叫本地變量。 這樣,我們就可以重新創建一個person,指定name和gender了。 ~~~ person = People.new('alex', 'man') #=> #<People:0x007fb961313ce8 @gender="man", @name="alex"> ~~~ 當然,你僅僅創建了@name和@gender這倆實例變量,這還不夠,你還不能給這倆實例變量賦值以及獲取它們的值。如下: ~~~ person.name #=> NoMethodError: undefined method `name' for #<People:0x007fb961313ce8 @name="alex", @gender="man"> ~~~ 所以,你必須要實現一對set/get方法。 我們再一次打開類,添加下面代碼: ~~~ class People def name @name end def name=(name) @name = name end def gender @gender end def gender=(gender) @gender = gender end end ~~~ 然后我們馬上再次執行下面代碼: ~~~ person.name #=> "alex" ~~~ 返回了我們期望的結果。我們也可以給person改名: ~~~ person.name = 'lee' person.walk person.say person.think ~~~ ### 開放類 如果你跟著上面的代碼走下來,會發現, 我們兩次都是直接打開People這個類來修改,每次修改都沒有重新添加之前的代碼,而People這個類生成的對象的行為,卻是只增不減。 尤其是你從其他語言轉過來的話,比如Java,會感到奇怪。 沒錯,這正是Ruby的特性之一: Open Class,開放類。 Ruby的類是可以隨便打開的,非常自由。 自由所帶來的結果是,有可能會被濫用,比如,你可以打開Ruby內置的類來添加方法: ~~~ class String def to_iii self.to_i end end "111".to_iii #=> 111 ~~~ 這種方式,有可能會影響到String類內置的方法,因為你無法記住每一個內置的方法,假如你添加的方法和內置的方法重名的時候,就完了,Ruby是不會警告你的,這樣可能會引起非常嚴重的bug。 我們把這種方式叫做monkey patch。 意思就是這種方式,比較原始,就像猴子沒進化到人這么高級一樣。 不過Ruby2.1給出了一個方案,具體可以參考我的blog的相關文章:[「Ruby2.1 Refinements」告別Monkey Patches](http://tao.logdown.com/posts/171266-ruby21-refinements-farewell-to-monkey-patches),這里不再累述。 ### Chef的monkey patchs 在Chef這個工具里,也使用了這種方式: 鏈接:[https://github.com/opscode/chef/blob/master/lib/chef.rb](https://github.com/opscode/chef/blob/master/lib/chef.rb) 可以看到: ~~~ require 'chef/monkey_patches/tempfile' require 'chef/monkey_patches/string' require 'chef/monkey_patches/numeric' require 'chef/monkey_patches/object' require 'chef/monkey_patches/file' require 'chef/monkey_patches/uri' ~~~ 先不用管require這個方法,這是Chef對于Ruby原生的類,添加了自己的方法。被添加的這個方法,應該是想要被所有的相關對象都可以響應。比如,我們打開「chef/monkey_patches/object」 ~~~ class Object unless new.respond_to?(:tap) def tap yield self return self end end end ~~~ 可以看到, Chef這種添加方式還是比較安全的。它加了一層保護,「unless new.respond_to?(:tap)」, 只有Object的對象不能響應這個tap方法,它定義的這個tap方法才可被響應。 這樣起到一個很好的保護作用。 ### 模塊 模塊,使用module關鍵字來定義的,你可以把它當做一組方法集合。比如有一群人,他們有共同的興趣,比如踢球、看球、打dota。 但是這些興趣并不是所有人類都有的,這個時候就需要模塊了。 ~~~ module Interest def kickball puts "i like kicking ball" end def read puts "i like reading books" end def dota puts "i like playing dota" end end ~~~ 然后我們就可以為某個人賦予這些興趣: ~~~ person = People.new('張三', 'man') person.extend Interest person.kickball #=> "i like kicking ball" person.read #=> "i like reading books" person.dota #=> "i like playing dota" ~~~ 注意,這里person是一個對象,我們可以使用extend來把Interest模塊的方法來拓展給person,讓他也擁有這些興趣。這種方式,叫做Mixin。 模塊,也可以作為命名空間來使用: ~~~ class Chef module Mixin module Command # ... end module Template # ... end end end ~~~ 這樣,我們可以使用Chef::Mixin::Command和Chef::Mixin::Template來使用這兩模塊,這就起到一個命名空間的作用。 ### 繼承 我們可以使用模塊來為類添加一組方法, 當然也可以使用繼承來添加一個子類。 那我們剛才的例子來說,有一組相同興趣的人群, 他們首先是人類,然后才是有這種興趣的人。 ~~~ class Fan < People def kickball puts "i like kicking ball" end def read puts "i like reading books" end def dota puts "i like playing dota" end end ~~~ 我們定義一個類Fan, 使用 < 關鍵字來讓這個類繼承自People,那么Fan就擁有了People的所有屬性和行為。 ~~~ person = Fan.new('李四', 'man') person.kickball #=> "i like kicking ball" ~~~ 同樣,李四和前面的張三,擁有了相同的對象。 我們可以把繼承和模塊結合起來使用, 因為興趣分很多類型,有運動、閱讀、打游戲,而運動種類,閱讀的種類和游戲的種類也很多,結合起來使用,會讓我們的代碼更加靈活: ~~~ module SportInterest def walk; 'walk' end def run; 'run' end def swimming; 'swimming' end # ... end module ReadInterest def read_book; 'read book' end def watching_tv; 'watching tv' end # ... end module GameInterest def cs; 'play cs' end def dota; 'play dota' end def wow; 'play wow' end # ... end class SportFan < People include SportInterest end class ReadFan < People include ReadInterest end class GameFan < People include GameInterest end ~~~ 這樣,我們可以隨便為各個興趣模塊里面添加各種項目,也不會影響到相關的Fan類。 再加上命名空間的概念,重構下上面代碼,就是下面這樣: ~~~ module Interest module Sport def walk; 'walk' end def run; 'run' end def swimming; 'swimming' end # ... end module Read def read_book; 'read book' end def watching_tv; 'watching tv' end # ... end module Game def cs; 'play cs' end def dota; 'play dota' end def wow; 'play wow' end # ... end end class SportFan < People include Interest::Sport end class ReadFan < People include Interest::Read end class GameFan < People include Interest::Game end ~~~ 這樣,代碼是不是看著更清晰了。
                  <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>

                              哎呀哎呀视频在线观看