Оволодіння об’єктно-орієнтованим програмуванням в Ruby

Ruby — це повністю об'єктно-орієнтована мова програмування (OOP), що означає, що майже все в Ruby є об'єктом. Парадигма OOP Ruby дозволяє легко писати чистий, багаторазовий і модульний код. У цьому блозі ми розглянемо основи об'єктно-орієнтованого програмування в Ruby, включаючи класи, об'єкти, спадкування, поліморфізм, інкапсуляцію та модулі — все це з детальними прикладами.

1. Що таке об'єктно-орієнтоване програмування?

OOP — це парадигма програмування, яка організовує код у вигляді об'єктів. Об'єкти є екземплярами класів, які інкапсулюють дані (атрибути) та поведінку (методи). Модель OOP Ruby надає ключові функції:

  • Інкапсуляція: Приховування внутрішнього стану об'єктів та вимога, щоб усі взаємодії здійснювались через методи.
  • Спадкування: Можливість класу наслідувати інший клас, отримуючи його методи та атрибути.
  • Поліморфізм: Використання загального інтерфейсу для різних типів даних або класів.

2.

Класи та об'єкти

Клас — це шаблон для створення об'єктів. Об'єкти — це конкретні екземпляри класу. В Ruby створення та використання об'єктів є інтуїтивно зрозумілим.

Приклад коду:

# Визначаємо клас  
class Person  
  attr_accessor :name, :age

  def initialize(name, age)  
    @name = name  
    @age = age  
  end

  def greet  
    "Hello, my name is #{@name} and I am #{@age} years old."  
  end

  def birthday  
    @age += 1  
    "Happy Birthday! #{@name} is now #{@age} years old."  
  end  
end

# Створення об'єктів  
person1 = Person.new("Alice", 30)  
person2 = Person.new("Bob", 25)

# Виклик методів об'єктів  
puts person1.greet # Виведення: Hello, my name is Alice and I am 30 years old.  
puts person2.birthday # Виведення: Happy Birthday! Bob is now 26 years old.

3. Спадкування

Спадкування дозволяє класу (дитині) успадковувати атрибути та методи від іншого класу (батька).
Ruby використовує символ <, щоб позначити спадкування.

Приклад коду:

# Батьківський клас  
class Animal  
  attr_reader :name

  def initialize(name)  
    @name = name  
  end

  def speak  
    "#{@name} makes a sound."  
  end  
end

# Дитячий клас  
class Dog < Animal  
  def speak  
    "#{@name} barks."  
  end  
end

# Дитячий клас  
class Cat < Animal  
  def speak  
    "#{@name} meows."  
  end  
end

# Створення об'єктів  
dog = Dog.new("Rex")  
cat = Cat.new("Whiskers")  
puts dog.speak # Виведення: Rex barks.  
puts cat.speak # Виведення: Whiskers meows.

4. Поліморфізм

Поліморфізм дозволяє об'єктам різних класів відповідати на той самий виклик методу своїм унікальним способом.
Це досягається через перевизначення методів.

Приклад коду:

class Employee  
  def initialize(name, salary)  
    @name = name  
    @salary = salary  
  end

  def details  
    raise "Цей метод повинен бути перевизначений підкласами."  
  end  
end

class Manager < Employee  
  def details  
    "#{@name} is a Manager earning $#{@salary} per year."  
  end  
end

class Developer < Employee  
  def details  
    "#{@name} is a Developer earning $#{@salary} per year."  
  end  
end

# Використовуємо поліморфізм  
employees = [Manager.new("Alice", 100000), Developer.new("Bob", 80000)]  
employees.each do |employee|  
  puts employee.details  
end  

# Виведення:  
# Alice is a Manager earning $100000 per year.  
# Bob is a Developer earning $80000 per year.

5. Інкапсуляція

Інкапсуляція обмежує доступ до внутрішнього стану об'єкта і дозволяє змінювати його лише через визначені методи.
Ruby досягає цього за допомогою приватних або захищених методів.

Приклад коду:

class BankAccount  
  def initialize(balance)  
    @balance = balance  
  end

  # Публічний метод для показу балансу  
  def show_balance  
    "Your balance is $#{@balance}."  
  end

  # Публічний метод для поповнення рахунку  
  def deposit(amount)  
    if valid_transaction?(amount)  
      @balance += amount  
      "Deposited $#{amount}. New balance is $#{@balance}."  
    else  
      "Invalid transaction."  
    end  
  end 

  private  
  # Приватний метод для перевірки транзакцій  
  def valid_transaction?(amount)  
    amount > 0  
  end  
end

account = BankAccount.new(1000)  
puts account.show_balance # Виведення: Your balance is $1000.  
puts account.deposit(500) # Виведення: Deposited $500. New balance is $1500.  
puts account.deposit(-100) # Виведення: Invalid transaction.

6. Модулі та міксини

Модулі групують багаторазові методи і можуть бути змішані в класи за допомогою include або extend.
Вони надають спосіб поділитися поведінкою між кількома класами.

Приклад коду:

module Flyable  
  def fly  
    "#{self.class} is flying!"  
  end  
end
class Bird  
  include Flyable  
end

class Plane  
  include Flyable  
end

bird = Bird.new  
plane = Plane.new  

puts bird.fly # Виведення: Bird is flying!  
puts plane.fly # Виведення: Plane is flying!

7.

Складний приклад: реальне застосування

Давайте створимо бібліотечну систему, щоб продемонструвати всі принципи об'єктно-орієнтованого програмування разом.

Приклад коду:

module Searchable  
  def find_by_title(title)  
    @items.find { |item| item.title == title }  
  end  
end
class Library  
  include Searchable

  def initialize  
    @items = []  
  end

  def add_item(item)  
    @items << item  
  end

  def list_items  
    @items.map(&:details).join("\n")  
  end  
end

class Book  
  attr_reader :title

  def initialize(title, author)  
    @title = title  
    @creator = author  
  end

  def details  
    "Book: #{@title} by #{@creator}"  
  end  
end

class DVD  
  attr_reader :title

  def initialize(title, director)  
    @title = title  
    @creator = director  
  end

  def details  
    "DVD: #{@title} directed by #{@creator}"  
  end  
end

library = Library.new  
book = Book.new("1984", "George Orwell")  
dvd = DVD.new("Inception", "Christopher Nolan")  
library.add_item(book)  
library.add_item(dvd)  

puts library.list_items  
# Виведення:  
# Book: 1984 by George Orwell  
# DVD: Inception directed by Christopher Nolan

item = library.find_by_title("1984")  
puts item.details # Виведення: Book: 1984 by George Orwell

Висновок

Особливості об'єктно-орієнтованого програмування Ruby надають інструменти для створення модульного, багаторазового та підтримуваного коду.
Оволодіваючи класами, об'єктами, спадкуванням, поліморфізмом, інкапсуляцією та модулями, ви зможете повною мірою використовувати потенціал Ruby для створення масштабованих застосунків. Практикуйте ці концепції та експериментуйте зі своїми проектами, щоб поглибити розуміння!

Перекладено з: Understanding Object-Oriented Programming in Ruby

Leave a Reply

Your email address will not be published. Required fields are marked *