Caution
お使いのブラウザはJavaScriptが実行できない状態になっております。
当サイトはWebプログラミングの情報サイトの為、
JavaScriptが実行できない環境では正しいコンテンツが提供出来ません。
JavaScriptが実行可能な状態でご閲覧頂くようお願い申し上げます。
継承 / 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』を返します。 |
サンプルコード
# 親クラスの定義。
class Animal
attr_reader :name, :sound
def initialize(name, sound)
@name = name
@sound = sound
end
def speak
"#{@name}が「#{@sound}」と言いました。"
end
def info
"動物: #{@name}"
end
end
# 子クラスの定義(Animal を継承)。
class Dog < Animal
attr_reader :breed
def initialize(name, breed)
super(name, "ワン") # 親クラスの initialize を呼び出します。
@breed = breed
end
# オーバーライド: 親クラスのメソッドを上書きします。
def info
super + "(犬・#{@breed})" # 親の info に追加します。
end
def fetch(item)
"#{@name}が#{item}を取ってきました!"
end
end
class Cat < Animal
def initialize(name)
super(name, "ニャン")
end
end
# インスタンスの生成と使用。
dog = Dog.new("ポチ", "柴犬")
cat = Cat.new("タマ")
puts dog.speak # ポチが「ワン」と言いました。
puts cat.speak # タマが「ニャン」と言いました。
puts dog.info # 動物: ポチ(犬・柴犬)
puts dog.fetch("ボール") # ポチがボールを取ってきました!
# 継承の確認。
puts dog.is_a?(Dog) # true
puts dog.is_a?(Animal) # true(親クラスも is_a? で true)
puts Dog.superclass # Animal
概要
Rubyのクラスは『class 子 < 親』で単一継承を実現します。サブクラスは親クラスのすべてのインスタンスメソッドを引き継ぎ、必要なメソッドだけをオーバーライドできます。
『super』の挙動は記述方法によって異なります。引数なしの『super』は現在のメソッドの引数をそのまま親に渡し、『super()』は引数なしで呼び出し、『super(args)』は指定した引数を渡します。混乱しやすい部分なので、明示的に書くことをお勧めします。
『initialize』で『super』を呼び忘れると、親クラスのインスタンス変数が初期化されません。サブクラスで『initialize』を定義したら、原則として『super』(または必要な初期化処理)を最初に呼ぶようにしてください。
モジュールを使った多重継承の代替手段については『module / include / extend』を、比較演算子のカスタマイズは『Comparable / <=>』を参照してください。
記事の間違いや著作権の侵害等ございましたらお手数ですがこちらまでご連絡頂ければ幸いです。