7-6-2 税込み額計算用クラスを継承を使って書き換えよう

クラス継承して税込み額計算用クラスを定義する

以下のようにプログラムを記述し、ファイル名をinherit_class.rbで保存します。

# 税込み額計算用クラスを継承を使って書き換えよう
class TaxCalculateBase
  TAX_RATE = 0.08

  attr_accessor :price

  def initialize(price: 0)
    @price = price
  end

  def tax
    (@price * TAX_RATE).to_i
  end

  def tax_included
    @price + tax
  end
end

class TaxCalculator < TaxCalculateBase
  def to_array
    [tax, tax_included]
  end

  def to_hash
    { tax: tax, tax_included: tax_included }
  end
end

# TaxCalculatorクラスのインスタンスを生成
calculator = TaxCalculator.new(price: 100)

# 税抜き額・税金・税込み額・計算結果の配列・ハッシュを表示
p calculator.price
p calculator.tax
p calculator.tax_included
p calculator.to_array
p calculator.to_hash

# 税抜き額を変更して実行
calculator.price = 200
p calculator.to_array
p calculator.to_hash

クラス継承したプログラムを実行する

コマンドライン上で保存したプログラムを実行します。実行結果に1008108[8, 108]{:tax=>8, :tax_included=>108}[16, 216]{:tax=>16, :tax_included=>216}の順で表示されます。

$ ruby inherit_class.rb
100
8
108
[8, 108]
{:tax=>8, :tax_included=>108}
[16, 216]
{:tax=>16, :tax_included=>216}

元クラスにprivateを定義する

以下のようにプログラムを修正し保存します。

# 税込み額計算用クラスを継承を使って書き換えよう
class TaxCalculateBase
  TAX_RATE = 0.08

  attr_accessor :price

  def initialize(price: 0)
    @price = price
  end

  private

    def tax
      (@price * TAX_RATE).to_i
    end

    def tax_included
      @price + tax
    end
end

class TaxCalculator < TaxCalculateBase
  def to_array
    [tax, tax_included]
  end

  def to_hash
    { tax: tax, tax_included: tax_included }
  end
end

# TaxCalculatorクラスのインスタンスを生成
calculator = TaxCalculator.new(price: 100)

# 税抜き額・税金・税込み額・計算結果の配列・ハッシュを表示
p calculator.price
p calculator.to_array
p calculator.to_hash
p calculator.tax_included

privateを追加したプログラムを実行する

コマンドライン上で修正したプログラムを実行します。実行結果に100[8, 108]{:tax=>8, :tax_included=>108}が表示された後、tax_includedメソッドがprivateメソッドであることを示すNoMethodErrorが表示されます。

$ ruby inherit_class.rb
100
[8, 108]
{:tax=>8, :tax_included=>108}
inherit_class.rb:39:in `<main>': private method `tax_included' called for #<TaxCalculator:0x00007fa5b6845658 @price=100> (NoMethodError)

親クラスのメソッドを上書きして再定義する

以下のようにプログラムを修正し保存します。

# 税込み額計算用クラスを継承を使って書き換えよう
class TaxCalculateBase
  TAX_RATE = 0.08

  attr_accessor :price

  def initialize(price: 0)
    @price = price
  end

  def tax
    (@price * TAX_RATE).to_i
  end

  def tax_included
    @price + tax
  end
end

class TaxCalculateFomatter < TaxCalculateBase
  def format(format_type: :hash)
    format_type == :hash ? to_hash : to_array
  end

  private

    def to_array
      [tax, tax_included]
    end

    def to_hash
      { tax: tax, tax_included: tax_included }
    end
end

class TaxCalculator < TaxCalculateFomatter
  def format(format_type: :hash)
    p "format_type is #{format_type}."
    super
  end
end

# TaxCalculateFomatterクラスのインスタンスを生成
formatter = TaxCalculateFomatter.new(price: 100)

# 計算結果を表示
p formatter.format

# TaxCalculatorクラスのインスタンスを生成
calculator = TaxCalculator.new(price: 200)

# 計算結果を表示
p calculator.format(format_type: :array)

親クラスのメソッドを上書きしたプログラムを実行する

コマンドライン上で修正したプログラムを実行します。実行結果に{:tax=>8, :tax_included=>108}"format_type is array."[16, 216]が表示されます。

$ ruby inherit_class.rb
{:tax=>8, :tax_included=>108}
"format_type is array."
[16, 216]