多重継承まとめ

JavaはInterfaceという特殊な実装を持たないものだけ多重継承できる。実装を多重継承する仕組みはない。同じシグネチャのメソッドを持っている2つのInterfaceを継承した際にエラーにならないので衝突に気付けない。

Pythonはクラスを多重継承できる。同じ名前のメソッドを持っている2つのクラスを継承した際にどのメソッドが呼ばれるかはC3線形化を使って決定される。see: A Monotonic Superclass Linearization for Dylan

RubyはModuleという「なにかを継承することはできなくてインスタンス化もできないもの」だけは多重継承できる。Moduleが別のものを継承できないためメソッドの解決は素朴な探索でOK(include A include BしたらBでの実装が優先)

SmalltalkにはTraitという実装の多重継承ができるしくみがある。同じシグネチャのメソッドを持っている2つのTraitを継承した際に、片方を隠して衝突を回避したり、名前を変更して両方呼べるようにしたりできる。 see: Traits: Composable Units of Behavior

ScalaのTraitは名前はTraitだがSmalltalkのとは大きく違う。同じシグネチャのメソッドを持っている2つのTraitを継承した際に、片方を隠して衝突を回避したり、名前を変更して両方呼べるようにしたりすることができない。メソッドにoverride修飾子がついていない場合はエラー、付いている場合はPythonと同じように直列化を使ってどのメソッドを呼ぶか決定する。

Perl6からRoleが入る。これはSmalltalkのTraitとほぼ同じもの。see http://publius-ovidius.livejournal.com/314737.html

PHPJava風の単一継承、インターフェイスとかも持っている。PHP5.4からTraitが入る。これはPerlのRoleとほぼ同じもの。PHP: rfc:traits [PHP Wiki]

Acknowledgement

Python以外の知識は id:sumim, id:moriyoshi, id:kmizushima に教えていただきました。ありがとうございます!

Q&A

id:yujiorama C++/D が無いのはなんでだろう。既知だからか

C++, D, C#, OCaml, Eiffel, その他数多くのオブジェクト指向言語の記述が抜けているのは、たまたま話題に上がらなかったか、簡潔に整理できなかったか、書いても面白く無かったからです。 You can contribute!