言語
日本語
English

Caution

お使いのブラウザはJavaScriptが無効になっております。
当サイトでは検索などの処理にJavaScriptを使用しています。
より快適にご利用頂くため、JavaScriptを有効にしたうえで当サイトを閲覧することをお勧めいたします。

Ruby辞典

  1. トップページ
  2. Ruby辞典
  3. 継承 / super / override

継承 / super / override

Rubyのクラス継承とメソッドオーバーライドの構文です。『super』を使って親クラスのメソッドを呼び出す方法を解説します。

構文

# 親クラスを継承してサブクラスを定義します。
class サブクラス名 < 親クラス名
  def initialize(引数)
    super(引数)  # 親クラスの initialize を呼び出します。
    @追加変数 = 値
  end

  # 親クラスのメソッドをオーバーライドします。
  def メソッド名
    super        # 引数をそのまま渡して親クラスのメソッドを呼び出します。
    追加処理
  end

  def メソッド名(引数)
    super(引数)  # 特定の引数を渡して呼び出します。
  end
end

# 親クラスの確認。
サブクラス.superclass    # 直接の親クラスを返します。
サブクラス.ancestors     # 継承チェーン全体を配列で返します。
オブジェクト.is_a?(クラス)  # そのクラス(またはサブクラス)のインスタンスか判定します。

メソッド一覧

構文 / メソッド概要
class 子 < 親親クラスを継承したサブクラスを定義します。親のメソッドをすべて引き継ぎます。
super同名の親クラスのメソッドを呼び出します。引数はそのまま引き継がれます。
super(args)指定した引数で親クラスのメソッドを呼び出します。
super()引数なしで親クラスのメソッドを呼び出します(引数の引き継ぎをしません)。
superclass直接の親クラスを返すクラスメソッドです。
ancestors継承チェーン(クラスとモジュールの順序)を配列で返します。
is_a?(klass)指定したクラスのインスタンスまたはサブクラスのインスタンスなら『true』を返します。

サンプルコード

sample_inheritance_super.rb
# 親クラスの定義。
class Fighter
  attr_reader :name, :technique

  def initialize(name, technique)
    @name = name
    @technique = technique
  end

  def battle_cry
    "#{@name}が「#{@technique}」を放ちました。"
  end

  def info
    "戦士: #{@name}"
  end
end

# 子クラスの定義(Fighter を継承)。
class SaiyanFighter < Fighter
  attr_reader :race

  def initialize(name, race)
    super(name, "かめはめ波")  # 親クラスの initialize を呼び出します。
    @race = race
  end

  # オーバーライド: 親クラスのメソッドを上書きします。
  def info
    super + "(#{@race})"  # 親の info に追加します。
  end

  def transform(level)
    "#{@name}がスーパーサイヤ人#{level}に変身しました!"
  end
end

class NamekianFighter < Fighter
  def initialize(name)
    super(name, "魔貫光殺砲")
  end
end

# インスタンスの生成と使用。
saiyan = SaiyanFighter.new("孫悟空", "サイヤ人")
namekian = NamekianFighter.new("ピッコロ")

puts saiyan.battle_cry    # 孫悟空が「かめはめ波」を放ちました。
puts namekian.battle_cry  # ピッコロが「魔貫光殺砲」を放ちました。
puts saiyan.info          # 戦士: 孫悟空(サイヤ人)
puts saiyan.transform(3)  # 孫悟空がスーパーサイヤ人3に変身しました!

# 継承の確認。
puts saiyan.is_a?(SaiyanFighter)  # true
puts saiyan.is_a?(Fighter)        # true(親クラスも is_a? で true)
puts SaiyanFighter.superclass     # Fighter
ruby inheritance_super.rb
孫悟空が「かめはめ波」を放ちました。
ピッコロが「魔貫光殺砲」を放ちました。
戦士: 孫悟空(サイヤ人)
孫悟空がスーパーサイヤ人3に変身しました!
true
true
Fighter

概要

Rubyのクラスは『class 子 < 親』で単一継承を実現します。サブクラスは親クラスのすべてのインスタンスメソッドを引き継ぎ、必要なメソッドだけをオーバーライドできます。

『super』の挙動は記述方法によって異なります。引数なしの『super』は現在のメソッドの引数をそのまま親に渡し、『super()』は引数なしで呼び出し、『super(args)』は指定した引数を渡します。混乱しやすい部分なので、明示的に書くことをお勧めします。

『initialize』で『super』を呼び忘れると、親クラスのインスタンス変数が初期化されません。サブクラスで『initialize』を定義したら、原則として『super』(または必要な初期化処理)を最初に呼ぶようにしてください。

モジュールを使った多重継承の代替手段については『module / include / extend』を、比較演算子のカスタマイズは『Comparable / <=>』を参照してください。

記事の間違いや著作権の侵害等ございましたらお手数ですがまでご連絡頂ければ幸いです。