違うよ、全然違うよ。
Javaのsuperはthisに対するスーパー
super
は親クラスの機能を使いたいときにthis
の代わりに使います。this
はそのオブジェクト自身です。そしてsuper
は端的に言うと「もし、今のクラスでなくて、親クラスのインスタンスとして作られた場合の振る舞いをするthis
」です。
例えばコンストラクタで、オーバーロードした現在のクラスの別のコンストラクタを呼び出す時にthis(arg)
と書くのと同じように、親クラスのコンストラクタを呼び出す時はsuper(arg)
と書きます。自オブジェクトについて現在のクラスのインスタンスメソッドを呼び出す時にthis.method(arg)
と書くのと同じように、親クラスのメソッドを呼び出す時はsuper.method(arg)
と書きます。つまりは、this
の代わりにsuper
を使うと、あたかも親クラスでthis
と書いているときと同じようになると言うことです。
ただし、例外的にthis
には無い書き方として、クラス名.super
という書き方もできます。また、同じdefaultメソッドを持つインターフェースを多重継承した場合の曖昧さ回避のためにインターフェース名.super
という書き方もあります。
Rubyのsuperはメソッドに対するスーパー
対して、Rubyのsuper
は「親クラスにある同名のメソッドを呼び出すメソッド」です。つまり、メソッドを書く代わりにsuper
を使うと言うことになります。super
自体がメソッド呼び出しであり、self
(RubyにおけるJavaのthis
相当)を置き換えるものではありません。なので、Javaのsuper
とは違って、今動作しているメソッドと同じ名前のメソッドしか呼び出せません。親クラスにある上書きされた別のメソッドを呼び出したい場合は、上書き前に別名を付けておくなど別のアプローチを用いる必要があります。
注意して欲しいのは、initialize
のおいてはJavaのコンストラクタと似たような書き方になりますが、意味が全く違うということです。Rubyのinitialize
はコンストラクタではありません。コンストラクタに相当するものはクラスメソッドになっているnew
であり、new
のデフォルトの動作として、オブジェクト生成(Class#allocate)後にinitialize
を呼び出すと言うだけにすぎません。つまり、initialize
は他と同じようにただのインスタンスメソッドに過ぎないと言うことです。なので、単にsuper
と書いた場合、親クラスのinitialize
を呼び出すという動作になるということです。
その他の言語
- C++: 多重継承するため親クラスを一意に決められないためか、
super
に相当する物はありません。クラス名を指定して呼び出す必要があります。
- JavaScript(ECMAScript): Javaとほぼ同じく
super
を使い、動作もほぼ同じです。
- C#:
base
というキーワードを使いますが、動作はJavaとほぼ同じです。
- Python:
super()
という組込関数を用いた方法を使っています。super()
はJavaのsuper
のようなオブジェクトを返す関数であり、Javaと似たような動作になります。ただし、Pytonの__init__()
はRubyと同じくコンストラクタでは無く、オブジェクト作成時に呼び出されるメソッドに過ぎないため、Javaのコンストラクタのような書き方はできず、通常のメソッドにおける親クラスのメソッド呼び出しのような書き方になります。PythonはC++と同じく多重継承ですが、順番に見に行くルールが決まっているため、C++のような問題は起きません。