superについての理解をまとめていく。effective ruby 項目7
superとは?
super は現在のメソッドがオーバーライドしているメソッドを呼び出します。括弧と引数が省略された場合には現在のメソッドの引数がそのまま引き渡されます。引数を渡さずにオーバーライドしたメソッドを呼び出すには super() と括弧を明示します。
Ruby リファレンス3.1マニュアル
クラスを継承した際に継承元と同じメソッドを使いたい場合にsuperを使う。superの呼び出し方は括弧や引数の書き方によってメソッドの呼ばれ方が変わるみたい。
基本的な使い方
継承元(スーパークラス)と同じメソッドを呼び出して実行する。superの方が先に実行される。
class Animal
def bark
puts "鳴き声"
end
def a
"a"
end
end
class Dog < Animal
def bark
super
puts "わんわん"
end
def habitat
super
puts "陸"
end
def a
result = super
puts result
end
end
dog = Dog.new
dog.bark
<<< 鳴き声
<<< わんわん
dog.habitat
<<< `habitat': super: no superclass method `habitat' for #<Dog:0x00007f8a2d00e010> (NoMethodError)
dog.a
<<< a
継承元クラスに存在しないhabitatメソッドを呼び出すとNoMethodErrorになる。aメソッドのように処理結果をもらうこともできる。
括弧と引数の書き方
オーバーライドメソッドの呼び出し方によって挙動が変わる場合がある。
class Animal
def age(x)
puts "#{x}歳です"
end
end
class Dog < Animal
def age(x)
super(x)
super x
super
super(x + 1)
super()
end
end
dog = Dog.new
dog.age(4)
<<< 4
<<< 4
<<< 4
<<< 5
<<<`age': wrong number of arguments (given 0, expected 1) (ArgumentError)
superのみだと引数が渡されるが、super()で引数無し括弧だと引数が渡されずArgumentErrorが出ることに注意。
どんな場合に使える?
親クラスと子クラスがあり、子クラスで親クラスのメソッドを呼び出したい時。
共通の処理を基底クラスを用意して他のクラスでオーバーライドメソッドを呼び出すことでそれぞれ別の処理を進められる。