クラスを使う場面
商品名と価格、口座名義と残高のように、常に一緒に扱うデータと操作がある場合にクラスが役立ちます。
クラスにする目安
- 一緒に扱う複数の値がある
- その値への操作が複数ある
- 不正な状態を防ぐルールがある
初期化とメソッド
initializeがnew時の初期化、@nameがインスタンスごとの変数です。
ProductRUBY
class Product
attr_reader :name, :price
def initialize(name, price)
raise ArgumentError, "商品名は必須です" if name.empty?
raise ArgumentError, "価格は0以上です" if price.negative?
@name = name
@price = price
end
def label
"#{name}(#{price}円)"
end
end
book = Product.new("Ruby入門", 2_000)
puts book.label実行結果OUTPUT
Ruby入門(2000円)attr_readerは読み取り用メソッドを作ります。変更を許す必要がなければattr_accessorを安易に使いません。
クラスメソッド
特定のインスタンスではなく、クラス自身に関係する処理はself.付きで定義します。
生成用メソッドRUBY
class Product
def self.free_sample(name)
new(name, 0)
end
end
sample = Product.free_sample("試供品")
puts sample.price実行結果OUTPUT
0このコードは前節のProductへ追加します。
継承より委譲を検討する
継承は「AはBの一種」と言える関係に使います。別機能を利用するだけなら、オブジェクトを受け取る委譲が変更しやすい設計です。
通知を委譲RUBY
class ConsoleNotifier
def send(message)
puts "通知: #{message}"
end
end
class OrderService
def initialize(notifier)
@notifier = notifier
end
def complete
@notifier.send("注文が完了しました")
end
end
OrderService.new(ConsoleNotifier.new).complete実行結果OUTPUT
通知: 注文が完了しましたミニ課題:銀行口座
口座名義と残高を持ち、預け入れと引き出しを行うBankAccountを作ります。0以下の金額や残高超過は例外にしてください。