[Day15] 再厲害的能力者一碰到海樓石就會喪失戰鬥力!
今天要和大家介紹 Ruby 裡的存取控制(Access control)
先來看看維基百科怎麼說:
存取控制
是指允許或禁止某人使用某項資源的能力。
聽起來是不是超強!
不過在 Ruby 裡,存取控制其實就是方法的使用層級。當我們在類別裡定義方法時,還可以再更明確指出這個方法是只有誰才可以取用,共分為三種:
- public
- private
- protected
Public
如果沒有特別寫是哪種存取方式,就會預設用 public
來存取我們定義的方法。
在撰寫存取控制的層級時,與方法定義前綴詞同一行即可:
1 | class Cafe |
換句話說,平常不寫 public
也沒關係,除非你在定義了 private
方法後又要定義 public
方法才要特別加上去,不過通常我們是不會這樣做的,後面會提到原因。
Private
private
則是指所定義的方法不能有明確的訊息接收者(receiver),意思就是不能用.
來呼叫方法
像是 puts
就是一種很常見的 private
方法,不過我們自己定義一個 private 方法 seasoning
試試看:
1 | class Cafe |
我開的咖啡廳裡面沒有絕妙的香氣!
private 寫的方法要用在哪裡?
看來 private
的方法沒辦法像之前的方式直接呼叫,那它到底是用在哪裡呢?事實上,Ruby 裡用 private
寫的方法是拿來在類別內部呼叫的,像是這樣:
1 | class Cafe |
private 方法在子類別也可以存取
在 Ruby 裡,private
寫的方法不只在類別內部可以存取,繼承自這個類別的子類別也一樣可以!
1 | class Father |
我也想要有個這樣的老爸(羨慕)
來看看 private 方法有哪些!
可以用 self.class.private_methods.sort
來找 :
1 | self.class.private_methods.sort |
發現了嗎? private
和 public
都是 private 方法!
其實也不是這麼 private
那… private
裡面的方法是不是就再也無法拿出來用呢?其實也未必。我們可以用 .send()
來取出 private
方法,只是這樣會破壞封裝的原則,非不得已建議不要這樣做。
1 | class Man |
果然成功拿出來了!
Protected
這是一個既不 public 又不 private 的東西。
protected
和 private
最大的不同,是 protected
可以允許在呼叫時前面有 receiver
,這種承繼自 SmallTalk 的設計理念是 Ruby 的一大特點,不過可能之後才會詳細介紹這段。
但由於實際上現在幾乎沒有人在用 protected
寫 Ruby 的存取控制,就讓它慢慢地成為時代的眼淚吧!
1 | class Smalltalk |
如果是用 protected
,那麼在內部呼叫時要寫 self.hello
或hello
都可以,但改成寫 private
,self.hello
就會出錯了。
存取控制的另一種寫法
也可以這樣寫:
1 | class Gem |
這麽一來,emerald
就變成了 protected
方法,而 diamond
成為了 private
方法
總結
public
、protected
和 private
的特點有三:
- 類別內部都可以呼叫 3 種類型的方法。
- 只有
public
方法能在外部被呼叫。 - 正常情況下
private
的方法不允許有receiver
,protected
則沒有這種限制。不過用send()
可以取消private
原本的限制。
在實際撰寫時,我們會把 private
的方法定義在類別的最下方,這樣就能知道 private
上方的通通都是 public
的方法,也能更輕鬆地閱讀程式碼。
關於 Ruby 方法的存取控制,今天就介紹到這邊啦!