superキーワード

 

Rubyのsuper


class Parent
def speak(word)
word
end
end

class Child < Parent
def speak(word)
super
end
end

child = Child.new

puts child.speak('hello') => hello

  • スーパークラス(またはインクルードしたモジュール)のメソッドを呼び出す構文。両方に定義されている場合はモジュールのメソッドが優先される。
  • superの呼び元メソッドと同名のインスタンスメソッドを直上のスーパークラスから探す。二つ以上上のスーパークラスのメソッドを呼ぶことは出来ない。
  • インスタンスメソッドの中でのみ使える。クラスメソッドの中でsuperを記述するとエラーになる。
  • 引数無しでsuperを呼んだ場合は、super呼び元メソッドに渡された引数と同じ引数がスーパークラスのメソッドに渡される。
  • 引数をつけてsuper(var1,va2,...)を呼んだ場合は、その引数をスーパークラスのメソッドに渡す。

Javaのsuper


// スーパークラス
String speak(String word){
return word;
}

// サブクラス側
String meth(String word){
return super.speak(word);
}

RubyJavaのコンストラクタの動作の違い


class HogeSuper
def initialize
puts 'hello'
end
end

class Hoge < HogeSuper
def initialize
end
end

Hoge.new

このコードを実行しても何も出力されない。
Javaであれば、Hogeのコンストラクタにsuperが自動で挿入されてhelloが出力されるが、Rubyのinitializeメソッドはsuperを明示的に書かなければスーパークラスのinitializeを呼ぶことはない。

次に、上のコードを以下のように修正する。


class HogeSuper
def initialize
puts 'hello'
end
end

class Hoge < HogeSuper
end

Hoge.new

実行するとhelloと出力される。
これはJavaの場合と同じ結果だが、内部の動作は違う。
Javaの場合、コンストラクタを省略するとデフォルトコンストラクタが定義され、
その中にsuper()が挿入されることでスーパークラスのコンストラクタが呼ばれる。
Rubyの場合は、initializeが定義されていないクラスをnewすると、単純にスーパークラスから受け継がれたinitializeメソッドが呼ばれる。
結局のところinitializeメソッドは、newメソッドによって呼ばれるというだけで本質は他の一般的なメソッドと変わらない。
ちなみにObjectクラスに空のinitializeメソッドが定義されているので、どんなオブジェクトもinitialize呼び出しに答えられる。