昨天,我們正式讀完 《Practical Object-Oriented Design in Ruby: An Agile Primer》,想必大家一定還是也些模模糊糊,意猶未盡!!
接下來想和大家分享自己這一年來在寫程式上重要的觀念,我相信只要將觀念釐清一定有助於降低大家在寫程式時遇到的一些阻礙。
在 Ruby 裡,萬物皆物件(Object)。物件有自己的狀態(state)與行為(behavior)。
Ruby中的物件(Object)
是一個類別(Class)
所製造出來的實體(Instance)
。我們可以將類別(Class)
想像成是物件的藍圖, 透過這份藍圖定義和實例化類別。
每個物件具備「接收訊息」與「傳遞訊息」給其他的物件,訊息的交換則是由類別內所定義的方法來實踐。
舉個簡單的狗狗貓貓例子,讓大家更有感覺一點~
# 定義一個類別 Dog
class Dog
#初始值
def initialize(name)
#定義實體變數(instance variable)
@name = name
end
# 定義一個方法 Speak 表現行為
def speak
"汪汪!"
end
end
# 創建 Dog 物件並呼叫 speak 方法
dog = Dog.new("狗")
puts dog.speak # 輸出 "汪汪!"
一旦經由<類別.new>這個過程後,我們就會得到一個實體物件,這個過程稱做instantiation
,例如:dog = Dog.new("狗")
,我們就有一個dog實體,dog之於程式碼為實體變數。
在 Ruby 裡,如果不小心使用相同類別的名字,類別的方法並不會被覆蓋或失效,而是會進行「融合」,例如:
# 定義一個類別 Dog
class Dog
#初始值
def initialize(name)
#定義實體變數(instance variable)
@name = name
end
# 定義一個方法 Speak 表現行為
def speak
"汪汪!"
end
end
class Dog
def eat
"潔牙骨"
end
end
dog = Dog.new("狗")
puts dog.speak # 輸出 "汪汪!"
puts dog.eat # 輸出 "潔牙骨"
也因為這個特性,我們可以在內建既有的類別(class)
去定義方法(method)
,例如:我想自定義一個array
的計算方法
class Array
def custom_sum
sum = 0
self.each { |item| sum += item }
sum
end
end
my_array = [1, 2, 3, 4, 5]
result = my_array.custom_sum
puts "The sum of the array is: #{result}" # 輸出 "The sum of the array is: 15"
延伸前面學習過的概念,物件導向程式語言利用「可重複性」的概念來增加軟體功能可維護性。類別可以通過繼承關係,讓子類別直接獲取父類別的特性,有助於減少重複撰寫相同程式碼。
同時,透過「鴨子類別」(duck typing)
的特性,也能夠更靈活地利用物件的行為,增進程式的適應性和可擴展性。
# 定義一個父類別 Animal
class Animal
def initialize(name)
@name = name
end
def speak
raise NotImplementedError, "子類別應該實現 speak 方法"
end
end
# 定義一個子類別 Dog,繼承自 Animal
class Dog < Animal
def speak
"汪汪!"
end
end
# 定義另一個子類別 Cat,也繼承自 Animal
class Cat < Animal
def speak
"喵喵!"
end
end
# 創建 Animal、Dog 和 Cat 的物件並呼叫 speak 方法
animal = Animal.new("動物")
dog = Dog.new("狗")
cat = Cat.new("貓")
puts animal.speak # 這裡會拋出 NotImplementedError,因為 Animal 類別的 speak 方法未實現
puts dog.speak # 輸出 "汪汪!"
puts cat.speak # 輸出 "喵喵!"
物件都是由類別創建出來,類別內的方法定義了物件的行為,我們可以在原生的類別定義新的行為,亦可藉由類別的繼承關係獲取共同行為。
參考資料: