[Day26] 卡魯鴨:我跑遍了沙漠,好渴啊!
自從學了 Ruby ,就常聽到別人在說 **鴨子型別(Duck Type)**,可是卻一直沒有弄得很懂,今天決定來了解什麼是鴨子型別!
開始囉!
型別
型別,是一種為了讓資源(位元組)更有效率地被利用而規劃的概念。簡單來說,每筆資料都有自己所屬的型別,譬如:整數、字串、陣列等等...
在鐵人賽第3天裡,我列出了一些 Ruby 常見的資料型別,各自做了簡單的介紹。但型別遠沒有這麼簡單啊!
Ruby 常被稱作是一種強型別的語言,然而,有強就有弱,判定標準在於語言能否自動轉換型態:像是 JavaScript,經常會偷偷地把變數轉換成可以被執行的資料型態(讓我覺得十分困擾)不過到了 Ruby 這裡,就會被仔細地檢查型別,型別不符的話則會發生錯誤。
還記得用怎麼類別產生實體物件嗎?產生實體物件也是一種將某個型別實體化的過程。
1 | String.new("卡魯鴨") |
動態型別?
接著,我們可能還要了解「動態型別」是什麼。
Ruby 被認為一種 動態型別(Dynamically Typed) 的語言,「動態、不固定」的意思是 在命名變數時,不用先宣告是哪種型別
有了動態型別,我們就能寫出較為簡潔的程式碼。同時,也因為不用先提供型態資訊,因此變數型態是可以改變的。
舉個例子,比方說先把字串"卡魯鴨"
指定給區域變數 a
:
1 | a = String.new("卡魯鴨") |
變數 a
的型別被換成整數(Integer)了!
鴨子?型別?
終於要切入今天重點了!
鴨子型別是一種程式設計的風格。這種風格認為,一個物件的型別不是由這個物件所屬的類別決定,而是由「它能做什麼」來決定。
如果你看到一隻鳥走起來像鴨子,游泳起來像鴨子;叫起來也像鴨子;那麼這隻鳥就可以被稱為鴨子。
換句話說,想知道一個物件是什麼型別,看它能使用什麼方法就好。
接下來用程式碼來解釋,現在有 Cat
和 Dog
兩個類別,彼此沒有相互繼承關係。
1 | class Cat |
再建立一個 Pet
類別,同時定義一個 who_is_hungry
方法可以傳入 name
,並讓 name
呼叫 hungry
執行:
1 | class Pet |
接著做出幾個實體:
1 | miru = Cat.new |
現在讓 miru
和 wolf
當作帶入的參數試試:
1 | pet.who_is_hungry(miru) |
用其他參數或另外的實體試試:
1 | pet.who_is_hungry(123) |
可以看到 pet.who_is_hungry
在傳入 miru
或 wolf
的當下,並沒有要求要檢查它們的型別,但是會確認它們都能執行 hungry
方法才能正常通過!
真是盡責的小鴨呢!
關於鴨子型別的的介紹就先到這邊啦!謝謝大家的觀看~