掌握Ruby世界就要先懂:類別 Class
上一篇文章簡單介紹物件導向 (OOP) 的設計模式,也稍微開個頭提到 Ruby 中的物件部分,有提到這句話:「Ruby 中的物件(Object)是一個類別(Class)所製造出來的實體(Instance)。」,也舉了例子表示物件由類別所產生出來。可以把類別想像成模具,而物件就是透過模具所刻印出來的實體。今天就來好好說明這個例子要表達的概念是甚麼,而類別又是甚麼吧。
類別 Class
類別中可以放置很多方法跟屬性,大家應該從前面對於物件導向的介紹中有看到,這些都寫在類別中。開始寫 rails 之後更是會注意到 Model 及 Controller 都是由 class 構築而成,且繼承自更上層的類別,這部分後面進入到 rails 的介紹會再有更多的說明。
定義類別
慣例上來說 class 會以大駝峰的方式來命名(CamelCase),例如 SayHello、PostsController、User。
1 | class 類別的名字 |
1 | class Human |
初始化 (initialize)
在使用 new 方法製作實體的時候,也可以順便傳參數進去,讓實體一建立就帶有相關的參數。
1 | class Human |
如果要透過 new 方法傳參數進來,在類別裡面必須有個名為 initialize 的方法來接收傳進來的參數。在 initialize 方法裡,常見的手法是會把參數傳進來給內部的實體變數(instance variable)。
實體變數 instance variable
類別內會建立實體,就會使用到實體變數,用 @ 開頭的變數,是活在每個實體裡的變數,而且每個實體之間互不相影響。
在 Rails 專案中,實體變數應用到的頻率很高,最常用的地方應該是 Controller 與 View 之間,會透過實體變數去進行傳遞資料。
1 | class UsersController < ApplicationController |
實體方法 (instance method)
1 | class Human |
類別方法 (class method)
以前面使用過的 user controller 的例子來看
1 | class UsersController < ApplicationController |
這裡的 all 方法是直接作用在 User 這個「類別」上,就稱為類別方法。在 Ruby 要定義類別方法有幾種寫法,其中一種比較簡單的,就是在前面加上 self:
1 | class Human |
這樣就可以直接用 Human.all 的方式呼叫方法。下面是另一種寫法:
1 | class Human |
這樣的寫法跟前面的一樣,但這樣就不需要特別在方法前面加上 self。當一個類別裡面有很多類別方法的時候,可以選擇這樣的寫法。
實體方法與類別方法比較
實體方法與類別方法的差異為作用的對象不同,實體方法是作用在實體上,而類別方法是作用在類別上。在 Ruby 中定義的方式也不同,定義類別方法則需要以 self
開頭或使用 class << self
裡面再定義方法,而實體方法則不用。
1 | class Human |
方法的類型與作用範圍
OOP 中的概念有提到一項是封裝的概念,主要可以利用一些私有方法來保護所定義的實體方法
- public: 就是所有區域都可以直接存取。
- private: 是只有在類別內部才可以存取。
- protected: 介於上述這兩者之間,比 private 寬鬆一些,但又沒有 public 那麼自由,protected 在同一個類別內,或是繼承它的子類別可以自由取用,且可以有 recevier。
比較:
三種方法都可以在 class 內部被呼叫。
只有 public 方法能在外部被呼叫。
在內部呼叫 private 方法的時候不能夠有 receiver,而 protected 方法則沒有這種限制。
繼承(inheritance)
上面都提到單一類別,如果除了人類類別外還想要再加入一個小狗類別呢?,而且都有相同的方法,我們可以利用繼承的設計,可以把程式碼整理更簡單,且不會寫出一堆重複的程式碼。
1 | class Human |
1 | class Dog |
在這個例子,不管是 Human 或 Dog 類別都有定義了 eat 方法,在物件導向的概念裡,如果這些類別的用途是同一型的(例如 Human 跟 Dog 都算動物),通常會把相同功能的方法移到「上一層」的類別裡,然後再去繼承它。
1 | class Animal |
創造出 Animal 類別,然後讓 Human 跟 Dog 都去繼承它,應用小於符號 < 就是「繼承」。可以代表「Human 是一種 Animal, Dog 也是一種 Animal」。
類別的部分觀念真的比較複雜,還有許多觀念後續如果有更多時間會再慢慢補充給大家。
參考資料: