Rubyについては自分で調べて基礎的なことはわかりました。
Ruby2.7.xについては以下のことがわかりました。
- 全てのクラスのクラスはClassクラスであって、ClassクラスのクラスもClassクラス自身。
- 全てのクラスのスーパークラスはObjectクラス。
- ただし、ObjectクラスのスーパークラスはBasciObjectクラス。ClassクラスのスーパークラスはModuleクラスであって、ModuleクラスのスーパークラスはObjctクラス。
つまり、Classクラス、Moduleクラス、Objectクラス、BasicObjectクラスが、継承関係とクラス-インスタンス関係によって循環している構造になっています。
質問したいことは、以下の二点です。
- 他のオブジェクト指向言語でもこのようにクラス関係が循環している構造をとっているのかどうか?
- なぜ、Rubyはこのような循環構造を取る戦略を取ったのか?
ご存知の方がいらっしゃいましたら教えていだだけると助かります。よろしくお願いします。
補足
- もちろん、継承関係とクラス-インスタンス関係は別物ですが、通常、継承関係であればスーパークラスが先に、クラス-インスタンス関係であればクラスが先に定義されている必要があります。これらの関係が混ざっていたとしても循環しているとどのクラスが先に定義されているのかがわからなくなります。
- Rubyであれば、クラス定義後にクラスを書き換えることがほぼ制限なしにできるので言語仕様としては可能ですが、他の言語ではどうなのだろう、というのが疑問の始まりです。
- もちろん、Interpreter/complier実行時にこのようなクラス関係が構築されるのか、実行以前に実装されているのかは言語実装によるのだろうと想像しています。
半端にタグを羅列するくらいなら「オブジェクト指向」だけにするか、言語を絞ったほうが良いです
> クラス関係が循環している
関係性は別に循環してないと思います
クラス実装のデータ構造的な循環は別の話です
ご指摘ありがとうございます。タグをオブジェクト指向だけにしました。
クラスの関係性については、下記の回答への返信として追加しました。
継承は別にループしていませんが、知りたいのは循環定義についてですか?
https://ja.m.wikipedia.org/wiki/%E5%BE%AA%E7%92%B0%E5%AE%9A%E7%BE%A9
おっしゃる通り継承関係はループしていないことは承知しています。
通常(おそらくどのオブジェクト指向言語でも)、インスタンスを作るためにはクラスが先に必要で、継承する場合もスーパークラスの存在が先に必要です。つまり、これらの関係が別物であっても、合わせて循環しているとどのクラスが先に作られているのかが辿れなくなります。
Rubyのようにオープンクラスをサポートしていたり、下記のご指摘のようにポインタなどを使えば、クラス定義後にこれらの関係性を書き換えることが可能ではありますが、そうする必然性がオブジェクト指向言語システムとしてあるのかないのかが、本質的に知りたいことです。
今広く使われている言語で循環定義のできない言語はないと思いますよ。前からしか読まない C 言語でも宣言と定義を分けることでできます。
いや、訂正します。Pascal は今でも後方参照が禁止されているようです。よく考えたら他にもありそうです。
あまりオブジェクト指向と関係ない部分の話ですよね。
どちらかといえばアルゴリズムの話に近いような。
> これらの関係が混ざっていたとしても
関係が混ざっているというのは、どういう意味でしょうか。
> どのクラスが先に定義されているのかがわからなくなります。
それを考える必要性がわかりません。
単なる知的好奇心です。すでに作られた言語を普通に使う分には必要性はほとんどないと思います。でも、もし、新しいオブジェクト指向言語(実装)を作ろうと思った時には、考える必要性はあると思いました。