基礎

Rubyのクラス入門|オブジェクト指向の基本とクラス定義の方法

クラスはオブジェクト指向プログラミングの基本概念で、データとそれに関連する処理をまとめた設計図(テンプレート)です。クラスから作成された実体を「オブジェクト」または「インスタンス」と呼びます。Rubyは純粋なオブジェクト指向言語であり、すべてのデータがオブジェクトです。

基本的な使い方

クラスの定義とインスタンスの作成

Ruby
class User
  def initialize(name, age)
    @name = name
    @age = age
  end

  def introduce
    puts "名前: #{@name}、年齢: #{@age}歳"
  end
end

# インスタンスの作成
user1 = User.new('太郎', 25)
user2 = User.new('花子', 22)

user1.introduce
user2.introduce
実行結果
名前: 太郎、年齢: 25歳
名前: 花子、年齢: 22歳

class クラス名でクラスを定義します。クラス名は大文字で始める慣例です。initializeメソッドはコンストラクタで、newでインスタンスを作成する際に自動的に呼ばれます。@name@ageはインスタンス変数で、各インスタンスが個別に保持するデータです。

インスタンスメソッド

クラス内で定義したメソッドはインスタンスメソッドとなり、各インスタンスから呼び出せます。

Ruby
class Calculator
  def initialize(value = 0)
    @value = value
  end

  def add(n)
    @value += n
    self  # メソッドチェーン用に自分自身を返す
  end

  def subtract(n)
    @value -= n
    self
  end

  def result
    @value
  end
end

calc = Calculator.new(100)
answer = calc.add(50).subtract(30).add(10).result
puts "計算結果: #{answer}"
実行結果
計算結果: 130

ゲッターとセッター

インスタンス変数は外部から直接アクセスできません。値を取得・設定するためのメソッドが必要です。

Ruby
class Product
  def initialize(name, price)
    @name = name
    @price = price
  end

  # ゲッター(値の取得)
  def name
    @name
  end

  # ゲッターとセッター
  def price
    @price
  end

  def price=(new_price)
    @price = new_price
  end

  def info
    "#{@name}: #{@price}円"
  end
end

product = Product.new('ノートPC', 89800)
puts product.name
puts product.price
product.price = 79800  # セッターで値を変更
puts product.info
実行結果
ノートPC
89800
ノートPC: 79800円

クラスメソッド

クラスメソッドはインスタンスではなくクラス自体から呼び出すメソッドです。self.を付けて定義します。

Ruby
class MathHelper
  def self.circle_area(radius)
    (3.14159 * radius ** 2).round(2)
  end

  def self.fahrenheit_to_celsius(f)
    ((f - 32) * 5.0 / 9).round(1)
  end
end

puts "半径5の円の面積: #{MathHelper.circle_area(5)}"
puts "100°F = #{MathHelper.fahrenheit_to_celsius(100)}°C"
実行結果
半径5の円の面積: 78.54
100°F = 37.8°C

実践的な使い方

Ruby
class BankAccount
  def initialize(owner, balance = 0)
    @owner = owner
    @balance = balance
  end

  def deposit(amount)
    @balance += amount
    puts "#{amount}円を入金しました(残高: #{@balance}円)"
  end

  def withdraw(amount)
    if amount > @balance
      puts "残高不足です(残高: #{@balance}円)"
    else
      @balance -= amount
      puts "#{amount}円を出金しました(残高: #{@balance}円)"
    end
  end

  def info
    puts "口座名義: #{@owner} / 残高: #{@balance}円"
  end
end

account = BankAccount.new('田中太郎', 10000)
account.info
account.deposit(5000)
account.withdraw(3000)
account.withdraw(20000)
account.info
実行結果
口座名義: 田中太郎 / 残高: 10000円
5000円を入金しました(残高: 15000円)
3000円を出金しました(残高: 12000円)
残高不足です(残高: 12000円)
口座名義: 田中太郎 / 残高: 12000円
インスタンス変数のスコープ

インスタンス変数(@で始まる変数)は同じインスタンスのすべてのメソッドからアクセスできます。ただし、クラスの外部からは直接アクセスできないため、ゲッター/セッターまたはattr_accessorが必要です。

initializeメソッドの注意点

initializenewで自動的に呼ばれる特殊なメソッドです。直接呼び出すことはできません。また、インスタンス変数はinitialize内で初期化するのが一般的です。未初期化のインスタンス変数にアクセスするとnilが返ります。

まとめ

  • class クラス名...endでクラスを定義する(名前は大文字始まり)
  • initializeメソッドがコンストラクタ(new時に呼ばれる)
  • @変数名でインスタンス変数を定義し、各インスタンスが個別にデータを保持
  • ゲッター/セッターでインスタンス変数への外部アクセスを制御する
  • self.メソッド名でクラスメソッドを定義できる