Try   HackMD

Ruby 開放類別、存取控制、模組

tags: Ruby

開放類別 open class

# 兩個同名的類別撞在一起不會覆蓋而是融合 class Cat def hello end end class Cat # 重複定義 def world end end kitty = Cat.new kitty.hello # 可正常運作 kitty.world # 可正常運作 幫現有的類別加功能,甚至內建的類別也做得到 class String def say_hello "オッス!オラ#{self}" end end puts "悟空".say_hello #=> 印出「オッス!オラ悟空」

存取控制

public / private / protected

class Cat def say_hello # default - public method # 實作 end private # 地圖炮 def gossip puts "我跟你說,你不能跟別人說" end end kitty = Cat.new kitty.say_hello kitty.gossip # 失敗

private 另一種寫法

class Cat def gossip puts "我跟你說,你不能跟別人說" end private :gossip end

receiver

其實 Ruby 的存取控制跟別人不一樣,特別是 private
private = 不能有明確的訊息接收者(receiver)
private = 呼叫方法的時候不會有小數點

class Cat def say_hello gossip end private def gossip # ... end end kitty = Cat.new kitty.gossip # 失敗 kitty.say_hello # 成功! # 其實 private 也不是那麼 private kitty.send(:gossip)

protected

protected = 不限定有沒有明確的訊息接收者
基本上你不太需要 protected

模組 module

問:我有一隻貓,我希望這隻貓會飛
答:建立一個鳥類別,然後叫貓去繼承它?但有點怪

定義 & 引入模組

module Flyable # 命名規定 = 必須是常數 def fly puts "I believe I can fly!" end end class Cat include Flyable # 引入模組 end kitty = Cat.new kitty.fly

使用模組跟類別的差別?

宇智波佐助的寫輪眼是透過 類別 繼承來的:

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

卡卡西是透過 include 寫輪眼模組,不用承受宇智波家的詛咒,也可以使用寫輪眼功能:

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

模組跟類別的差異?

# 模組沒有繼承的功能,所以不能這樣: module Flyable < SomeModule end # 模組不能實體化,所以不能這樣: module Flyable end wing = Flyable.new

模組的 include 與 extend

class Cat include Flyable # 引入 end kitty = Cat.new kitty.fly # 實體方法
class Cat extend Flyable # 擴充 end Cat.fly # 類別方法

namespace:如果遇到同名類別

你叫金城武,我也叫金城武
三重金城武 vs 土城金城武

module A class Cat # 包在A裡面 end end module B class Cat # 包在B裡面 end end # 連名帶姓 kitty = A::Cat.new nancy = B::Cat.new

冒號的位置

has_many :name # 符號 { name: "悟空", age: 18 } # key { direction: :up, power: 530000 } # key 跟 符號 class User < ActiveRecord::Base # ActiveRecord模組中的Base類別 end