淺析Ruby中繼承和訊息的相關知識_ruby專題

來源:互聯網
上載者:User

繼承允許你建立一個類,作為另一個類的精鍊(refinement)和特化(specialization)。例如,在我們的自動點唱機系統中,有“歌曲”這一概念,被封裝在Song類中,然後,隨著市場的成長,我們需要提供卡拉OK的支援。一首卡拉OK歌曲和其他歌曲沒什麼兩樣(它只是沒有主唱的音軌,對此我們不必關心)。不過,它還包括對於的一套歌詞以及時間資訊。當我們的自動點唱機在播放一首卡拉OK歌曲時,歌詞應該隨音樂滾動顯示在點唱機前的螢幕上。

解決這個問題的一種方法是定義一個新的類KaraokeSong,就是Song加上歌詞。

class KaraokeSong <Song  def initialize(name,artist,duration,lyrics)    super(name,artist,duration)    @lyrics = lyrics  endend

類定義一行中的“< Song”告訴Ruby, KaraokeSong是Song 的子類(subclass).因此,這也意味著Song是KaraokeSong的超類(superclass)

song = KaraokeSong.new("My Way","Sinatra",255,"And now,the ...")song.to_s        ->          *Song:My Way--Sinatra(225)*

調用to_s方法沒有顯示歌詞

這和我們在向一個對象發送訊息時,Ruby判定調用哪個方法的機制有關。在程式碼的初始解析(parse)期間,當Ruby遇到方法調用song.to_s時,它並不知道從何處找到to_s方法,而是將判定延遲直至程式開始運行時再運行。在那時,Ruby查看song所屬的類。如果該類實現了和訊息名稱相同的方法,就運行這個方法。否則,Ruby就查看其父類中的方法,然後是祖父類,凡此以往追溯整個祖先鏈。如果最終它在祖先類中沒有找到合適的方法,Ruby會產生一種特殊的行為,通常是導致引發一個錯誤。

讓我們通過實現KaraokeSong#to_s來解決這個問題,你有許多方法可以完成它。讓我們從最槽糕的方法開始,我們將to_s方法從Song類中拷貝出來並添加lyrics資訊。

class KaraokeSong #... def to_s   "KS: #@name--#@artist(#@duration){#@lyrics}"  endendsong = KaraokeSong.new("My Way", "Sinatra", 225,"And now,the...")song.to_s     ->"KS: My Way--Sinatra(225){And now,the...}"

我們正確地顯示了執行個體變數@lyrics的值。但使用這種方法,子類需要直接存取其祖先的執行個體變數。那麼為什麼這是實現to_s的一種糟糕方式呢?

答案與良好的編程風格有關(有時被稱為解耦)。直接戳進父類的內部結構,並且顯示地檢驗它的執行個體變數,會使得我們和父類的實現緊密地綁在一起。

我們通過讓每個類處理其自身實現細節的方法來解決這個問題。當調用KaraokeSong#to_s時,我們調用其父類的to_s方法來得到歌曲的細節。然後,將歌詞資訊添加上去,並返回結果。這裡使用的技巧是Ruby的關鍵字super。當你調用super而不使用參數時,Ruby向當前對象的父類發送一個訊息,要求它調用子類中的同名方法。Ruby將我們原先調用方法時的參數傳遞給父類的方法。現在,我們可以實現改進後新的to_s方法。

class KaraokeSong <Song  #Format ourselves as a string by appending  #our lyrics to our parent's to_s value.  def to_s    super+"{#@lyrics}"  endendsong = KaraokeSong.new("My Way", "Sinatra" ,225, "And now,the...")song.to_s      ->"Song:My Way--Sinatra(225){And now,the...}"

我們明確地告訴Ruby,KaraokeSong是Song的子類,但是我們並沒有指定Song類本身的父類是什麼。如果你在定義一個類時沒有指定其父類,Ruby預設以Object類作為其父類。這意味著所有類的始祖都是Object,並且Object的執行個體方法對Ruby的所有對象都可用。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.