Ruby 存取控制

圖片作者 Jozef Krajčovič  來源 http://jozefkrajcovic.sk/
圖片作者 Jozef Krajčovič
來源 http://jozefkrajcovic.sk/

Ruby 是一個完全物件導向程式語言,不管是字串、整數等,都是類別的物件。

在物件導向內,類別 (class)主要有方法 (method) 等組成,藉由呼叫方法來改變物件的狀態,Ruby 對方法的存取控制分為三個不同的層級,名稱與其他物件導向程式語言一樣,有 publicprotectedprivate

Public、Protected、Private 存取控制

在 Ruby 這三個存取控制層級與其他語言有不同之處,從其他語言跳到 Ruby 可能會忽略掉。

  • public 可以被任何人直接存取,例如:類別的物件可以呼叫 public 方法,預設所有的方法為 public,除了 #initialize 方法為 private
  • protected 層級比 public 小,只有相同類別或子類別內,才能存取 protected 方法
  • private 不能有明確的 receiver 呼叫 private 方法,表示 private 方法只能在物件內被呼叫

還是以下藉由程式來說明會更清楚!

存取控制

接著介紹撰寫方法的存取控制:

第一種寫法:

第一種寫法是將存取控制層級寫在方法前,此種寫法是存取控制層級後面的方法,都是遵照前面所寫的,直到遇到另一個存取控制層級。

如上面的程式碼,寫在 protected 之後的方法都是 protected 的存取層級,直到下一個存取層級,也就是 private,所以,在 protectedprivate 前的方法都是 protected

Person 類別內所有方法的存取層級分別為:

  • #initializeprivate
  • #introducepublic
  • #my_ageprotected
  • #talkprivate

PS. 在前面有提到,#initialize 預設為 private

第二種寫法:

第二個寫法是在方法之後,才定義方法的存取層級,分別在 protectedprivate 方法後面利用 symbol 來定義每個方法的存取控制層級。

接著我們來操作 Person 類別:

如果外部程式,要呼叫 Person#my_agePerson#talk 會發生錯誤,因為兩個方法分別為 protectedprivate

繼承

建立一個 Male 類別,Male 繼承了 Person 類別:

會發現第 7 行程式,在 Male#introduce 內,呼叫了 Person#talk,但是此方法為 private,為什麼 Ruby 可以這樣使用呢?

在一開始介紹 Ruby 的 private 存取控制層級就有提到,private不能被明確的 receiver 呼叫。在第 7 行內,#talk 並不沒有 receiver,所以在這裡是合法的,但是如果將第七行改成 self.talk my_sex 就會出現問題,因為 #talk 已經被明確的 receiver 也就是 self 呼叫了!

操作 Male 類別:

不過,還是有可以在外面程式呼叫 protected 及 private 方法,去參加開開心心學 Ruby 的時候,大大有提到可以利用 Object#send 來呼叫 protectedprivate 方法。

不過這樣做,並沒有違反 Ruby 定義的 protectedprivate,以 private 來說,因為並不是由 receiver 去呼叫的,而是透過 #send 方法。

更多詳細的介紹可以參考:http://blog.eddie.com.tw/2011/07/26/public-protected-and-private-method-in-ruby/

Ruby 存取控制

發表迴響

你的電子郵件位址並不會被公開。 必要欄位標記為 *