【Ruby入門】クラスの継承!オーバーライドやアクセス制御【#9】


こんにちは。Tomoyuki(@tomoyuki65)です。

クラスは一からコードを書いて作ることができますが、結構大変ですよね。

でもクラスには、継承という概念があるんです。

 

クラスの継承をすることで、一度作ったクラスを再利用し、新しいクラスを作成できるんです!

 

この記事では、そんなクラスの継承について解説します。

 



クラスの継承

クラスは、一からコードを書いて作ることもできますが、既に作成されたクラスを元に新しいクラスを作成することもできます。

これをクラスの継承と呼びます。

 

例として、商品クラスを元に食品クラスを作成してみましょう。

では以下プログラムを実行してみて下さい。

# 商品クラス
class Product
  def initialize(name, price)
    @product_name = name
    @product_price = price
  end

  # 商品名を出力するメソッド
  def output_name
    puts "商品名:#{@product_name}"
  end
end

# 食品クラス
class Food < Product
  # 価格を出力するメソッド
  def output_price
    puts "価格:#{@product_price}"
  end
end

# 牛肉オブジェクトを作成
beef = Food.new("牛肉", 1000)
beef.output_name
beef.output_price

 

実行結果
商品名:牛肉
価格:1000

 

実行結果の通り、商品クラスを継承して食品クラスが作成できました。

このように、クラスの継承ではクラスを一から作成することなく、共通の処理を引き継いでクラスを作成できます。

 

尚、今回の例のように継承元のクラス(商品クラス)を『親クラス』または『Super Class』継承先のクラス(食品クラス)を『子クラス』または『Sub Class』と呼びます。

 

また、子クラスでは、親クラスにある同名のメソッドを上書きすることが出来ます。

では以下のプログラムを実行してみて下さい。

# 商品クラス
class Product
  def initialize(name, price)
    @product_name = name
    @product_price = price
  end

  # 商品名を出力するメソッド
  def output_name
    puts "商品名:#{@product_name}"
  end
end

# 食品クラス
class Food < Product
  # 価格を出力するメソッド
  def output_price
    puts "価格:#{@product_price}"
  end

    # 食品名を出力するメソッドに上書きする
  def output_name
    puts "食品名:#{@product_name}"
  end
end

# 牛肉オブジェクトを作成
beef = Food.new("牛肉", 1000)
beef.output_name
beef.output_price

 

実行結果
食品名:牛肉
価格:1000

 

実行結果の通り、親クラスのメソッドが上書き出来ました。

このように、親クラスのメソッドを上書きすることを『メソッドのオーバーライド』と呼びます。

 



メソッドのアクセス制御

メソッドには以下のように三つのアクセス権がありますが、protectedは特殊な場合に使います。

まずはpublicやprivateについて覚えましょう。

 

メソッドのアクセス権

  •  public:通常はこの設定。どこからでもアクセス可能。但し、initializeメソッドとクラスの外に書いたメソッドは自動的にprivateなるので注意。
  •  protected:クラス外からアクセス不可。(特殊な場合に使う)
  •  private:クラス外からアクセス不可。かつレシーバーを指定出来ないメソッドになる。

 

では例として以下のプログラムを実行してみて下さい。

class SampleClass
  # 出力用メソッド(publicメソッド)
  def output_method
    # わかりやすいよう明示的にselfメソッドを記載
    self.public_method     # 実行結果 => OK
    self.protected_method  # 実行結果 => OK
    private_method        # 実行結果 => OK ※レシーバーを指定出来ない
  end

  # publicメソッドを定義
  def public_method
    puts "public_method"
  end

    # protectedメソッドを定義
  protected # この宣言より下に記載したメソッドに適用
    def protected_method
      puts "protected_method"
    end

    # privateメソッドを定義
  private # この宣言より下に記載したメソッドに適用
    def private_method
      puts "private_method"
    end
end

# アクセス権を確認する
SampleClass.new.output_method     # 実行結果 => OK
SampleClass.new.public_method     # 実行結果 => OK
SampleClass.new.protected_method  # クラス外からアクセス不可
SampleClass.new.private_method    # クラス外からアクセス不可

 

実行結果
public_method
protected_method
private_method
public_method
エラーメッセージ
protected method `protected_method’ called for #<SampleClass:0x005592c8d1cc60> (NoMethodError)
Did you mean? protected_methods

 

実行結果の通り、output_methodとpublic_methodは実行できますが、protected_methoとprivate_methodはクラス外からはアクセス不可のため実行出来ません。

このように、メソッドはアクセスを制御をすることが出来ます。

 

クラスの継承をした場合

次にクラスを継承した場合のアクセス制御について確認しましょう。

では以下プログラムを実行してみて下さい。

class SampleClass
  def output_method
    self.public_method
    self.protected_method
    private_method
  end

  def public_method
    puts "public_method"
  end

  protected
    def protected_method
      puts "protected_method"
    end

  private
    def private_method
      puts "private_method"
    end
end

# クラスの継承
class SecondClass < SampleClass
  def output
    puts "SecondClass"
    protected_method    # 親クラスのprotectedメソッドを実行
    private_method      # 親クラスのprivateメソッドを実行
  end
end

# アクセス権を確認する
SecondClass.new.output

 

実行結果
SecondClass
protected_method
private_method

 

実行結果の通り、クラスを継承した場合もprotected_methodとprivate_methodを呼び出すことが出来ます。

 

また、同名のメソッドを上書きすることも出来るので確認してみましょう。

では以下プログラムを実行してみて下さい。

class SampleClass
  def output_method
    self.public_method
    self.protected_method
    private_method
  end

  def public_method
    puts "public_method"
  end

  protected
    def protected_method
      puts "protected_method"
    end

  private
    def private_method
      puts "private_method"
    end
end

# クラスの継承
class SecondClass < SampleClass
  def output
    puts "SecondClass"
    protected_method
    private_method
  end

    # protected_methodをオーバーライド
  def protected_method
    puts "SecondClassのprotected_method"
  end

  # private_methodをオーバーライド
  def private_method
    puts "SecondClassのprivate_method"
  end
end

# アクセス権を確認する
SecondClass.new.protected_method
SecondClass.new.private_method

 

実行結果
SecondClassのprotected_method
SecondClassのprivate_method

 

実行結果の通り、メソッドのオーバーライドが出来ました。

このように、Rubyのアクセス制御では子クラスからprivateメソッドへのアクセスやオーバーライドが可能です。

他のオブジェクト指向のプログラミング言語と異なる部分があるので注意しましょう。

 



まとめ

  •  既に作成されたクラスを元に新しいクラスを作成でき、これをクラスの継承と呼ぶ
  •  メソッドのアクセス権はpublic、protected、privateの三つが存在する
  •  Rubyでは子クラスからprivateメソッドへのアクセスが可能なことや、オーバーライドが可能なことが他のプログラム言語と異なる部分があるため注意が必要

 

  •  関連記事

【無料あり】Ruby入門サイトおすすめ3選!初心者向けの学習方法を解説

2017年10月24日

【Ruby入門】クラスを作る!メソッドの違いやアクセサを覚える【#8】

2017年8月23日

テスト駆動開発を実践!Rubyでテストコードを書きながらクラスを作って遊ぶ!

2017年11月25日

 

The following two tabs change content below.

Tomoyuki

SEを5年経験後、全くの未経験ながら思い切ってブロガーに転身し、月間13万PVを達成。その後コロナの影響も受け、以前から興味があったWeb系エンジニアへのキャリアチェンジを決意。現在はWeb系エンジニアとして働きながら、プロゲーマーとしても活躍できるように活動中。








シェアはこちらから


【2024年】おすすめのゲーミングPC

モンハンワイルズの発売日とPC版(Steam版)の推薦スペックが公開されたので、おすすめのゲーミングPCをご紹介!


コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です