佳木斯湛栽影视文化发展公司

主頁(yè) > 知識(shí)庫(kù) > 淺析Ruby中繼承和消息的相關(guān)知識(shí)

淺析Ruby中繼承和消息的相關(guān)知識(shí)

熱門(mén)標(biāo)簽:Win7旗艦版 語(yǔ)音系統(tǒng) 客戶(hù)服務(wù) 企業(yè)做大做強(qiáng) 電話運(yùn)營(yíng)中心 硅谷的囚徒呼叫中心 百度AI接口 呼叫中心市場(chǎng)需求

繼承允許你創(chuàng)建一個(gè)類(lèi),作為另一個(gè)類(lèi)的精煉(refinement)和特化(specialization)。例如,在我們的自動(dòng)點(diǎn)唱機(jī)系統(tǒng)中,有“歌曲”這一概念,被封裝在Song類(lèi)中,然后,隨著市場(chǎng)的成長(zhǎng),我們需要提供卡拉OK的支持。一首卡拉OK歌曲和其他歌曲沒(méi)什么兩樣(它只是沒(méi)有主唱的音軌,對(duì)此我們不必關(guān)心)。不過(guò),它還包括對(duì)于的一套歌詞以及時(shí)間信息。當(dāng)我們的自動(dòng)點(diǎn)唱機(jī)在播放一首卡拉OK歌曲時(shí),歌詞應(yīng)該隨音樂(lè)滾動(dòng)顯示在點(diǎn)唱機(jī)前的屏幕上。

解決這個(gè)問(wèn)題的一種方法是定義一個(gè)新的類(lèi)KaraokeSong,就是Song加上歌詞。

class KaraokeSong Song

  def initialize(name,artist,duration,lyrics)

    super(name,artist,duration)

    @lyrics = lyrics

  end

end

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

song = KaraokeSong.new("My Way","Sinatra",255,"And now,the ...")

song.to_s        ->          *Song:My Way--Sinatra(225)*

調(diào)用to_s方法沒(méi)有顯示歌詞

這和我們?cè)谙蛞粋€(gè)對(duì)象發(fā)送消息時(shí),Ruby判定調(diào)用哪個(gè)方法的機(jī)制有關(guān)。在程序代碼的初始解析(parse)期間,當(dāng)Ruby遇到方法調(diào)用song.to_s時(shí),它并不知道從何處找到to_s方法,而是將判定推遲直至程序開(kāi)始運(yùn)行時(shí)再運(yùn)行。在那時(shí),Ruby查看song所屬的類(lèi)。如果該類(lèi)實(shí)現(xiàn)了和消息名稱(chēng)相同的方法,就運(yùn)行這個(gè)方法。否則,Ruby就查看其父類(lèi)中的方法,然后是祖父類(lèi),凡此以往追溯整個(gè)祖先鏈。如果最終它在祖先類(lèi)中沒(méi)有找到合適的方法,Ruby會(huì)產(chǎn)生一種特殊的行為,通常是導(dǎo)致引發(fā)一個(gè)錯(cuò)誤。

讓我們通過(guò)實(shí)現(xiàn)KaraokeSong#to_s來(lái)解決這個(gè)問(wèn)題,你有許多方法可以完成它。讓我們從最槽糕的方法開(kāi)始,我們將to_s方法從Song類(lèi)中拷貝出來(lái)并添加lyrics信息。

class KaraokeSong

 #...

 def to_s

   "KS: #@name--#@artist(#@duration){#@lyrics}"

  end

end

song = KaraokeSong.new("My Way", "Sinatra", 225,"And now,the...")

song.to_s     ->"KS: My Way--Sinatra(225){And now,the...}"

我們正確地顯示了實(shí)例變量@lyrics的值。但使用這種方法,子類(lèi)需要直接訪問(wèn)其祖先的實(shí)例變量。那么為什么這是實(shí)現(xiàn)to_s的一種糟糕方式呢?

答案與良好的編程風(fēng)格有關(guān)(有時(shí)被稱(chēng)為解耦)。直接戳進(jìn)父類(lèi)的內(nèi)部結(jié)構(gòu),并且顯示地檢驗(yàn)它的實(shí)例變量,會(huì)使得我們和父類(lèi)的實(shí)現(xiàn)緊密地綁在一起。

我們通過(guò)讓每個(gè)類(lèi)處理其自身實(shí)現(xiàn)細(xì)節(jié)的方法來(lái)解決這個(gè)問(wèn)題。當(dāng)調(diào)用KaraokeSong#to_s時(shí),我們調(diào)用其父類(lèi)的to_s方法來(lái)得到歌曲的細(xì)節(jié)。然后,將歌詞信息添加上去,并返回結(jié)果。這里使用的技巧是Ruby的關(guān)鍵字super。當(dāng)你調(diào)用super而不使用參數(shù)時(shí),Ruby向當(dāng)前對(duì)象的父類(lèi)發(fā)送一個(gè)消息,要求它調(diào)用子類(lèi)中的同名方法。Ruby將我們?cè)日{(diào)用方法時(shí)的參數(shù)傳遞給父類(lèi)的方法?,F(xiàn)在,我們可以實(shí)現(xiàn)改進(jìn)后新的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}"

  end

end

song = KaraokeSong.new("My Way", "Sinatra" ,225, "And now,the...")

song.to_s      ->"Song:My Way--Sinatra(225){And now,the...}"

我們明確地告訴Ruby,KaraokeSong是Song的子類(lèi),但是我們并沒(méi)有指定Song類(lèi)本身的父類(lèi)是什么。如果你在定義一個(gè)類(lèi)時(shí)沒(méi)有指定其父類(lèi),Ruby默認(rèn)以O(shè)bject類(lèi)作為其父類(lèi)。這意味著所有類(lèi)的始祖都是Object,并且Object的實(shí)例方法對(duì)Ruby的所有對(duì)象都可用。

您可能感興趣的文章:
  • Ruby類(lèi)繼承、抽象類(lèi)、類(lèi)拓展混入、代理類(lèi)實(shí)例
  • Ruby最簡(jiǎn)單的消息服務(wù)器代碼

標(biāo)簽:山西 喀什 山西 安康 長(zhǎng)沙 崇左 海南 濟(jì)南

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《淺析Ruby中繼承和消息的相關(guān)知識(shí)》,本文關(guān)鍵詞  ;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問(wèn)題,煩請(qǐng)?zhí)峁┫嚓P(guān)信息告之我們,我們將及時(shí)溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無(wú)關(guān)。
  • 相關(guān)文章
  • 收縮
    • 微信客服
    • 微信二維碼
    • 電話咨詢(xún)

    • 400-1100-266
    和田市| 兰溪市| 双峰县| 莫力| 临潭县| 新河县| 鄂托克旗| 新乐市| 贵南县| 蒙城县| 静海县| 屏南县| 岱山县| 顺平县| 广东省| 崇文区| 合作市| 吉林省| 永兴县| 云安县| 夹江县| 横山县| 子长县| 万盛区| 遵义市| 临沂市| 十堰市| 泰宁县| 阳高县| 玛多县| 平顶山市| 穆棱市| 新宾| 临沭县| 温泉县| 亳州市| 西吉县| 湘潭县| 富蕴县| 十堰市| 荔浦县|