Ruby

【Ruby】クラスの継承とオーバーライド

Rubyにおけるクラスの継承とオーバーライド

クラスの継承

ざっくり基本設計

目的:メンテナンス性を高める、使い勝手をよくする

手段:

1)基本的な機能を親クラスにて定義

2)独自のメソッドを子クラスにて定義

3)子クラスは親クラスを継承

具体例:

目的:飲食店のメニューを表示したい。

名前、値段、カロリー(※食べ物についてのみ)、容量(※飲み物についてのみ)

親クラス・・・食べ物/飲み物のメニューを表示するインスタンスメソッドを持つ。

名前:ハンバーガー 値段:¥800

名前:コーヒー 値段:\200

子クラス1・・・食べ物のカロリーを表示するインスタンスメソッドを持つ

カロリー:600kcal

子クラス2・・・飲み物の容量を表示するインスタンスメソッドを持つ

容量:300ml

 

・継承した子クラスには、親クラスのインスタンスメソッドとインスタンス変数が引き継がれる

実装(クラスの継承)

親クラス

class Menu
    attr_accessor :name
    attr_accessor :price
/*インスタンスを使用時、受け取った引数の値をインスタンス変数に代入して、class内で使えるようにする :/
    def initialize(name:, price:)
      self.name = name
      self.price = price
    end
/*infoメソッドの定義。受け取った引数の値を、名前・円の文字列にくっつけて返す */
    def info
    return”#{self.name}#{self.price}円”
    end
end

子クラス①

//親クラスMenuの継承
require “./menu”
class Food < Menu
end

子クラス②

//親クラスMenuの継承
require “./menu”
class Drink < Menu
end
出力ページ
require “./food”
require “./drink”
/* Foodクラスのインスタンスを生成。Foodクラスは親であるMenuクラスを継承しているので、Menuクラスで定義されたインスタンス変数name,priceも使用できる*/
food1 = Food.new(name:”ハンバーガー”, price:600)
/* Menuクラスで定義されたインスタンスメソッドinfoを使用*/
puts food1.info //結果)ハンバーガー 600円
/* 同上 */
drink1 = Drink.new(name:”コーヒー”,price:200)
puts drink1.info  //結果)コーヒー 200円

実装(子クラス独自のインスタンス変数・インスタンスメソッド)

子クラス①

//親クラスMenuの継承
require “./menu”
class Food < Menu
//子クラス独自のインスタンス変数
    attr_accessor :calorie
//子クラス独自のインスタンスメソッド
    def calorie_info
      return”#{self.name}は#{self.calorie}kcalです”
    end
end
子クラス②
//親クラスMenuの継承
require “./menu”
class Drink < Menu
//子クラス独自のインスタンス変数
    attr_accessor :amount
//子クラス独自のインスタンスメソッド
    def amount_info
      return “#{self.name}は#{self.amount}mLです”
    end
end
出力ページ

require “./food”
require “./drink”

food1 = Food.new(name: “ピザ”, price: 800)
food1.calorie = 700

//food1に対してcalorie_infoメソッドを呼び出して戻り値を出力
puts food1.calorie_info  //結果)ピザは700kcalです

drink1 = Drink.new(name:”コーヒー”, price: 300)
drink1.amount = 300

//drink1に対してamount_infoメソッドを呼び出して戻り値を出力

puts drink1.amount_info  //結果)コーヒーは300mLです

オーバーライド

目的:親クラスのメソッドを上書き

手段:親クラスにあるメソッドと同じ名前のメソッドを、子クラスで定義する

具体例:

目的:飲食店のメニューを表示したい。

名前、値段、カロリー(※食べ物についてのみ)、容量(※飲み物についてのみ)

親クラス・・・食べ物/飲み物のメニューを表示するインスタンスメソッドを持つ。

名前:ハンバーガー 値段:¥800

名前:コーヒー 値段:\200

子クラス1・・・食べ物の名前、値段、カロリーを表示するインスタンスメソッドを定義して、親クラスの、メニューを表示するインスタンスメソッドをオーバーライドする

ハンバーガー、¥800、600kcal

子クラス2・・・飲み物の名前、値段、容量を表示するインスタンスメソッドを定義して、親クラスの、メニューを表示するインスタンスメソッドをオーバーライドする

コーヒー、¥300、300ml

実装

親クラス
class Menu
  attr_accessor :name
  attr_accessor :price
/*インスタンスを使用時、受け取った引数の値をインスタンス変数に代入して、class内で使えるようにする :/
def initialize(name:, price:)
  self.name = name
  self.price = price
end
/*受け取った引数の値を、名前・円の文字列にくっつけて返す。オーバーライドの対象 */
    def info
      return”#{self.name}#{self.price}円”
    end
end
子クラス①
//親クラスMenuの継承
require “./menu”
class Food < Menu
//子クラス独自のインスタンス変数
    attr_accessor :calorie
//infoメソッドを定義して、親クラスのinfoメソッドをオーバーライド
    def info
      return”#{self.name}#{self.price}円 (#{self.calorie}kcal)”
    end
end
子クラス②
//親クラスMenuの継承
require “./menu”
class Drink < Menu
//子クラス独自のインスタンス変数
    attr_accessor :amount
//infoメソッドを定義して、親クラスのインスタンスメソッドをオーバーライド
    def info
      return”#{self.name}#{self.price}円 (#{self.amount}mL)”
    end
end
出力ページ
require “./food”
require “./drink”
/* Foodクラスのインスタンスを生成。Foodクラスは親であるMenuクラスを継承しているので、Menuクラスで定義されたインスタンス変数name,priceも使用できる*/
food1 = Food.new(name:”ハンバーガー”, price:600)
food1.calorie = 600
food2 = Food.new(name:”ポテト”, price:300)
food2.calorie = 500
drink1 = Drink.new(name: “コーヒー”, price: 300)
drink1.amount = 300
drink2 = Drink.new(name: “お茶”, price: 200)
drink2.amount = 400
menus = [food1, food2, drink1, drink2]
/* メニューを一覧表示*/
index = 0
menus.each do |menu|
    puts “#{index}. #{menu.info}” //ここでFoodクラスのinfoとDrinkクラスのinfoがそれぞれ使われる
    index += 1
end
出力結果)
0.ハンバーガー 600円(600kcal)
1.ポテト 300円(500kcal)
2.コーヒー 300円(300mL)
3.お茶 200円(400mL)