アクセス修飾子はメソッドの公開範囲を制御する仕組みです。Rubyにはpublic、private、protectedの3つのアクセス修飾子があり、これらを使ってクラスの外部からアクセスできるメソッドとできないメソッドを区別します。カプセル化(内部実装の隠蔽)はオブジェクト指向の重要な原則です。
基本的な使い方
public(デフォルト)
特に指定しない場合、メソッドはpublicになります。クラスの外部から自由に呼び出せます。
Ruby
class User
def greet # publicメソッド(デフォルト)
puts "こんにちは、#{full_name}です"
end
private
def full_name # privateメソッド
'田中太郎'
end
end
user = User.new
user.greet # OK: publicメソッド
# user.full_name # エラー!privateメソッドは外部から呼べない実行結果
こんにちは、田中太郎ですprivateと書いた行以降に定義されたメソッドはすべてprivateになります。privateメソッドはクラス内の他のメソッドからのみ呼び出すことができ、外部からのアクセスはエラーになります。
3つのアクセス修飾子の違い
Ruby
class Account
attr_reader :name, :balance
def initialize(name, balance)
@name = name
@balance = balance
end
# public: 外部から呼べる
def deposit(amount)
if valid_amount?(amount)
@balance += amount
log_transaction('入金', amount)
puts "#{amount}円を入金しました(残高: #{@balance}円)"
end
end
# public: 他のAccountと比較
def richer_than?(other)
balance > other.balance_value # protectedメソッドにアクセス
end
protected
# protected: 同じクラスのインスタンス間でアクセス可能
def balance_value
@balance
end
private
# private: このクラス内からのみ呼べる
def valid_amount?(amount)
if amount <= 0
puts 'エラー: 金額は正の数を指定してください'
false
else
true
end
end
def log_transaction(type, amount)
puts "[LOG] #{type}: #{amount}円"
end
end
acc1 = Account.new('太郎', 10000)
acc2 = Account.new('花子', 20000)
acc1.deposit(5000)
puts "太郎は花子より裕福?: #{acc1.richer_than?(acc2)}"
# acc1.balance_value # エラー!protectedは外部から呼べない
# acc1.valid_amount?(100) # エラー!privateは外部から呼べない実行結果
[LOG] 入金: 5000円
5000円を入金しました(残高: 15000円)
太郎は花子より裕福?: falseprivateメソッドの詳細
Ruby
class Calculator
def calculate(a, b, operation)
case operation
when :add then format_result(a, b, '+', add(a, b))
when :subtract then format_result(a, b, '-', subtract(a, b))
when :multiply then format_result(a, b, '*', multiply(a, b))
else puts '未対応の演算です'
end
end
private
def add(a, b)
a + b
end
def subtract(a, b)
a - b
end
def multiply(a, b)
a * b
end
def format_result(a, b, op, result)
puts "#{a} #{op} #{b} = #{result}"
end
end
calc = Calculator.new
calc.calculate(10, 3, :add)
calc.calculate(10, 3, :subtract)
calc.calculate(10, 3, :multiply)実行結果
10 + 3 = 13
10 - 3 = 7
10 * 3 = 30外部からはcalculateメソッドだけを呼び出せます。個々の計算処理(add、subtractなど)はprivateにすることで、内部実装を隠蔽しています。
個別にアクセス修飾子を指定
Ruby
class MyClass
def method_a
puts 'public method_a'
end
# 個別にprivateを指定する方法
private def method_b
puts 'private method_b'
end
def method_c
puts 'public method_c'
method_b # private methodを内部から呼ぶ
end
end
obj = MyClass.new
obj.method_a
obj.method_c
# obj.method_b # エラー!実行結果
public method_a
public method_c
private method_bprotectedの使いどころ
protectedは同じクラス(またはサブクラス)のインスタンス間でのみアクセスを許可します。主にオブジェクト同士の比較(==メソッドなど)で、内部の値にアクセスする必要がある場合に使います。
Rubyのprivateは絶対ではない
Rubyではsendメソッドを使うとprivateメソッドでも外部から呼び出せてしまいます(obj.send(:method_b))。privateはあくまで「誤って呼ばないようにする」ための仕組みであり、セキュリティ機能ではありません。
まとめ
public: 外部から自由に呼び出せる(デフォルト)private: クラス内部からのみ呼び出せるprotected: 同じクラスとサブクラスのインスタンス間でアクセス可能private以降のメソッドはすべてprivateになる- 内部実装を隠蔽することで、クラスの使いやすさと保守性が向上する