September 27, 2023

Viiisit [Ruby] - Ruby 的物件導向程式語言基礎概念!

#ruby#oop

在之前都是分享 JavaScript 相關的內容,接著想分享自己學習 Ruby 與 Ruby on Rails 時,
了解到的重要知識,都會再接下來的文章中出現唷!

Ruby 是什麼?

A dynamic, open source programming language with a focus on simplicity and productivity. It has an elegant syntax that is natural to read and easy to write.
一種動態的開源程式語言,注重簡單性和生產力。具有優雅的語法,易於閱讀且易於編寫。

Ruby 的作者是松本行弘(Yukihiro Matsumoto)
減少編程不必要的瑣碎時間,令編寫程式的人高興,是設計 Ruby 首要的考量點;
其次是良好的介面設計。他強調系統設計必須強調人性化,而不是一味從機器的角度設想

Ruby 是物件導向程式語言

在深入說明之前,先來理解物件導向程式設計(Object-Oriented Programming, OOP)

因此,物件導向程式設計是一種方法論,而物件導向程式語言是實現這種方法論的具體工具。
使用物件導向程式語言,開發者可以更容易地實現和應用物件導向程式設計的概念。


物件導向程式設計(Object-Oriented Programming, OOP)具有以下特點,
也透過 Ruby 的語法來舉一些簡單的例子加深印象:

  1. 類別(Classes)與物件(Objects)
    類別(Classes)是物件的藍圖或模板,定義了物件的結構和行為。基於類別可以創建多個具體的物件。
    物件(Objects)是類別的實例(Instance),這些物件具有狀態(屬性)和行為(方法)。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    # 定義一個狗的類別(Classes)
    class Dog
    def initialize(name, breed)
    @name = name
    @breed = breed
    end

    # 定義一個方法,用於描述狗的行為
    def bark
    "Woof Woof!"
    end

    # 定義一個方法,用於獲取狗的資訊
    def get_info
    "I'm #{@name}, a #{@breed}."
    end
    end

    # 建立一個名為 Yellow 的狗的物件實例
    dog1 = Dog.new("Yellow", "Golden")

    # 建立另一個名為 Gogo 的狗的物件實例
    dog2 = Dog.new("Gogo", "Husky")

    # 調用物件的方法來執行操作
    puts dog1.bark # Woof Woof!
    puts dog2.get_info # I'm Gogo, a Husky.

    定義了一個 Dog 類別,這個類別有兩個實例變數 @name@breed,分別表示狗的名字和品種。 initialize 方法用來初始化這些屬性,bark 方法用來描述狗叫的行為,get_info 方法用來取得狗的資訊,並創建了兩個物件,分別是 Yellow, Gogo。 每個物件都有自己的屬性(名字和品種),並且可以呼叫方法來執行不同的操作,這說明了物件具有自己的狀態和行為。

    在 Ruby 中,initialize 方法通常用於在建立物件實例時進行初始化操作,可以接受參數來設定物件的初始狀態。

  2. 封裝(Encapsulation)
    封裝是指的是將物件的內部狀態(屬性)和行為(方法)包裝在一個單一的單元中,
    並限制外部對內部的直接訪問。這有助於保護數據的完整性和安全性。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    class Dog
    # 初始化方法,用於設定狗的屬性
    def initialize(name)
    @name = name
    end

    # 定義一個公開的方法 bark,用於讓狗吠
    def bark
    "Woof Woof!"
    end
    end

    # 創建一個名為 Yellow 的狗的物件實例
    dog = Dog.new("Yellow")

    # 呼叫公開的方法 bark 來讓狗吠
    puts dog.bark # Woof Woof!

    Dog 類別,其中:

    • 有一個私有實例變數 @name,表示狗的名字。
    • 有一個公開的方法 bark,用於讓狗吠。

    在封裝的概念下,bark 方法是公開的,外部可以通過物件來呼叫這個方法,讓狗吠。
    但是,外部的使用者不需要知道狗究竟是如何吠的,這個實現細節被隱藏在類別的內部。

    總之,封裝的核心思想是將物件的內部狀態和行為隱藏起來,只提供一個公開的介面,讓外部使用者能夠與物件互動,而無需了解物件的內部實現細節。

  3. 繼承(Inheritance)
    繼承是一種機制,允許一個類別(子類別)基於另一個類別(父類別)來定義,
    繼承父類別的屬性和方法。
    這有助於實現代碼重用和建立層次化結構。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    class Animal
    def speak
    puts "Animal makes a sound."
    end
    end

    class Dog < Animal
    def speak
    puts "Dog barks."
    end
    end

    dog = Dog.new
    dog.speak # Dog barks.
  4. 多型(Polymorphism)
    多型允許不同的物件使用相同的接口執行不同的操作。
    提高了程式碼的靈活性和可擴展性,允許處理多種不同的物件類型。

    每種動物都可以發出聲音,但不同的動物發出不同的聲音。
    可以使用多型來實現這個概念:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    class Animal
    def speak
    "Animal makes a sound"
    end
    end

    class Dog < Animal
    def speak
    "Dog barks: Woof Woof!"
    end
    end

    class Cat < Animal
    def speak
    "Cat meows: Meow Meow!"
    end
    end

    class Bird < Animal
    def speak
    "Bird chirps: Chirp Chirp!"
    end
    end

    # 建立動物的陣列
    animals = [Dog.new, Cat.new, Bird.new]

    # 讓每個動物發聲
    animals.each do |animal|
    puts animal.speak
    end

    在這個例子中,我們建了一個基本的 Animal 類別,並讓每種動物(DogCatBird)都繼承這個基本類別。然後,我們在每個子類別中重寫 speak 方法,以提供特定動物的聲音。

    最後,我們創建了一個包含不同動物的陣列,使用迴圈讓每個動物發聲。這就是多型的簡單例子,不同類別的物件可以呼叫相同的方法名稱(speak),但根據物件的實際類別而執行不同的動作。

  5. 抽象化(Abstraction)
    抽象化是將物件的共通特徵和行為提取出來,形成一個抽象的類別或接口。
    這有助於減少複雜性並提高可理解性。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    class Animal
    def initialize(name)
    @name = name
    end

    def speak
    end
    end

    class Dog < Animal
    def speak
    "#{@name} barks: Woof Woof!"
    end
    end

    # 創建一隻名叫 Yellow 的狗
    dog = Dog.new("Yellow")

    puts dog.speak # Yellow barks: Woof Woof!
  6. 消息傳遞(Message Passing)
    指一個物件通過接受訊息、處理訊息、傳出訊息或使用其他類別的方法來實作一定功能。
    有一個 Dog 類別,每隻狗都可以執行一些特定的動作,例如 bark(叫)和 fetch(撿東西)。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    class Dog
    def bark
    "Woof Woof!"
    end

    def fetch(item)
    "Fetch the #{item}!"
    end
    end

    # 創建一隻名叫大黃的狗
    dog = Dog.new

    # 發送消息給大黃來執行動作
    # 透過呼叫這些方法,實際上是向狗物件發送了相應的訊息,以執行相應的動作。
    puts dog.bark # Woof Woof!
    puts dog.fetch("ball") # Fetch the ball!
  7. 動態性(Dynamic Binding)
    物件導向通常支持動態繫結,指方法會隨著實例動態的改變。這增加了彈性和可擴展性。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    class Animal
    def speak
    puts "Animal makes a sound."
    end
    end

    class Dog < Animal
    def speak
    puts "Dog barks."
    end
    end

    animal = Animal.new
    dog = Dog.new

    animal.speak # "Animal makes a sound."
    dog.speak # "Dog barks."

參考資料:
物件導向程式設計
物件導向(Object Oriented Programming)概念
Ruby 物件導向程式語言(Object Oriented Programming)