"Class methods are a special kind of Singleton Method - and just as baffling"
定義類別方法時需在方法前加上 self。
class Cat < Animal
# instance method for instance object
def speak
"meow"
end
# class method is also a singleton method
def self.jump
"jumping"
end
end
p Cat.singleton_methods # => [:jump]
在上面程式碼中,可從 Cat.singleton_methods 證實類別方法也是 singleton method。
有了對 Singleton classes 的基本認識後,本章節來聊聊 Singleton classes 、classes 與 superclasses 之間的關聯。
以下面的程式碼為例子:
class Animal
# instance method for every instance object of Animal
def run
@str = "running"
end
end
class Cat < Animal
# instance method for every instance object of Cat
def speak
"meow"
end
end
# Add a class method/singleton method to Animal class
class Animal
class << self
def a_class_method
"C.a_class_method"
end
end
end
kitty = Cat.new
# Add a singleton method to kitty object
class << kitty
def scratch
"scratching"
end
end
箭頭 C 指向的物件並不等於類別方法(class method)住的地方,因為類別方法並不知道 singleton class 的存在。舉例來說:如果你問 kitty 的類別是什麼? Ruby 是會回傳 Cat ,但是其實 kitty 的類別應該是 kitty 的 singleton class, aka " #kitty " 。
Cat.superclass # => #<Class:Animal>
Animal.singleton_class # => #<Class:Animal>
Cat.singleton_class # => #<Class:Cat>
Cat.singleton_class.superclass # => #<Class:Animal>
Animal.singleton_class.superclass # => #<Class:Object>
( # 代表是 singleton class, #Cat 就是 singleton class of Cat)
可從上圖得知:
#Cat 的 superclass 是 #Animal,同時也是 Animal 的 singleton class。
同樣地,#Animal 的 superclass 就是 #Object。
因此我們可以這樣說:
" The superclass of the singleton class is the singleton class of the superclass" from Metaprogramming Ruby
昏頭了嗎?其實多看幾次就會懂了!那也許有人會問:為什麼 Ruby 要把 class、superclass 及 singleton class 之間的關聯設計的如此令人困惑呢?答案是因為這樣的設計讓我們可以在子層(subclass)就可以呼叫到父層的類別方法。
Cat.a_class_method # => "Animal.a_class_method"
也許在 Cat 類別呼叫 Animal 類別所擁有的方法是再正常不過的事情了,不就是繼承所得到的方法嗎?
但是現在終於了解 Ruby 背後運作的幕後工程。