iT邦幫忙

2023 iThome 鐵人賽

DAY 13
0

在之前都是分享 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),這些物件具有狀態(屬性)和行為(方法)。

    # 定義一個狗的類別(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)
    封裝是指的是將物件的內部狀態(屬性)和行為(方法)包裝在一個單一的單元中,
    並限制外部對內部的直接訪問。這有助於保護數據的完整性和安全性。

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

    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)
    多型允許不同的物件使用相同的接口執行不同的操作。
    提高了程式碼的靈活性和可擴展性,允許處理多種不同的物件類型。

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

    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)
    抽象化是將物件的共通特徵和行為提取出來,形成一個抽象的類別或接口。
    這有助於減少複雜性並提高可理解性。

     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(撿東西)。

    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)
    物件導向通常支持動態繫結,指方法會隨著實例動態的改變。這增加了彈性和可擴展性。

    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."
    

今天就先分享到這裡,我們下篇見!

參考資料:

文章同步於個人部落格:Viiisit!(歡迎參觀 ୧ʕ•̀ᴥ•́ʔ୨)


上一篇
Day 12 - 理解 JavaScript,為什麼要知道 ES6 的語法糖 Class?
下一篇
Day 14 - 理解 OOP 物件導向程式設計的基本原則 - SOLID
系列文
從零開始,在 coding 路上的 30 個為什麼?不對!是無數個為什麼!30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言