質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
オブジェクト指向

オブジェクト指向プログラミング(Object-oriented programming;OOP)は「オブジェクト」を使用するプログラミングの概念です。オブジェクト指向プログラムは、カプセル化(情報隠蔽)とポリモーフィズム(多態性)で構成されています。

Q&A

2回答

871閲覧

オブジェクト指向言語のクラス階層/継承関係について

.M.

総合スコア98

オブジェクト指向

オブジェクト指向プログラミング(Object-oriented programming;OOP)は「オブジェクト」を使用するプログラミングの概念です。オブジェクト指向プログラムは、カプセル化(情報隠蔽)とポリモーフィズム(多態性)で構成されています。

0グッド

0クリップ

投稿2020/08/25 20:03

編集2020/08/26 06:13

Rubyについては自分で調べて基礎的なことはわかりました。

Ruby2.7.xについては以下のことがわかりました。

  1. 全てのクラスのクラスはClassクラスであって、ClassクラスのクラスもClassクラス自身。
  2. 全てのクラスのスーパークラスはObjectクラス。
  3. ただし、ObjectクラスのスーパークラスはBasciObjectクラス。ClassクラスのスーパークラスはModuleクラスであって、ModuleクラスのスーパークラスはObjctクラス。

つまり、Classクラス、Moduleクラス、Objectクラス、BasicObjectクラスが、継承関係とクラス-インスタンス関係によって循環している構造になっています。

質問したいことは、以下の二点です。

  1. 他のオブジェクト指向言語でもこのようにクラス関係が循環している構造をとっているのかどうか?
  2. なぜ、Rubyはこのような循環構造を取る戦略を取ったのか?

ご存知の方がいらっしゃいましたら教えていだだけると助かります。よろしくお願いします。

補足

  • もちろん、継承関係とクラス-インスタンス関係は別物ですが、通常、継承関係であればスーパークラスが先に、クラス-インスタンス関係であればクラスが先に定義されている必要があります。これらの関係が混ざっていたとしても循環しているとどのクラスが先に定義されているのかがわからなくなります。
  • Rubyであれば、クラス定義後にクラスを書き換えることがほぼ制限なしにできるので言語仕様としては可能ですが、他の言語ではどうなのだろう、というのが疑問の始まりです。
  • もちろん、Interpreter/complier実行時にこのようなクラス関係が構築されるのか、実行以前に実装されているのかは言語実装によるのだろうと想像しています。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

m.ts10806

2020/08/26 00:05 編集

半端にタグを羅列するくらいなら「オブジェクト指向」だけにするか、言語を絞ったほうが良いです
退会済みユーザー

退会済みユーザー

2020/08/26 00:57 編集

> クラス関係が循環している 関係性は別に循環してないと思います クラス実装のデータ構造的な循環は別の話です
.M.

2020/08/26 05:11

ご指摘ありがとうございます。タグをオブジェクト指向だけにしました。 クラスの関係性については、下記の回答への返信として追加しました。
.M.

2020/08/26 06:20

おっしゃる通り継承関係はループしていないことは承知しています。 通常(おそらくどのオブジェクト指向言語でも)、インスタンスを作るためにはクラスが先に必要で、継承する場合もスーパークラスの存在が先に必要です。つまり、これらの関係が別物であっても、合わせて循環しているとどのクラスが先に作られているのかが辿れなくなります。 Rubyのようにオープンクラスをサポートしていたり、下記のご指摘のようにポインタなどを使えば、クラス定義後にこれらの関係性を書き換えることが可能ではありますが、そうする必然性がオブジェクト指向言語システムとしてあるのかないのかが、本質的に知りたいことです。
Zuishin

2020/08/26 06:28 編集

今広く使われている言語で循環定義のできない言語はないと思いますよ。前からしか読まない C 言語でも宣言と定義を分けることでできます。 いや、訂正します。Pascal は今でも後方参照が禁止されているようです。よく考えたら他にもありそうです。
退会済みユーザー

退会済みユーザー

2020/08/26 06:31 編集

あまりオブジェクト指向と関係ない部分の話ですよね。 どちらかといえばアルゴリズムの話に近いような。
退会済みユーザー

退会済みユーザー

2020/08/26 06:54

> これらの関係が混ざっていたとしても 関係が混ざっているというのは、どういう意味でしょうか。
maisumakun

2020/08/26 07:37

> どのクラスが先に定義されているのかがわからなくなります。 それを考える必要性がわかりません。
.M.

2020/08/27 07:29 編集

単なる知的好奇心です。すでに作られた言語を普通に使う分には必要性はほとんどないと思います。でも、もし、新しいオブジェクト指向言語(実装)を作ろうと思った時には、考える必要性はあると思いました。
guest

回答2

0

継承関係とクラス-インスタンス関係

そららを混ぜれば循環ですが、継承関係と、クラス-インスタンス関係は別物なので、それらをごちゃ混ぜにして「循環」と考えるのがおかしいと思います。

投稿2020/08/25 22:55

otn

総合スコア85901

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

.M.

2020/08/26 05:07

ご指摘ありがとうございます。確かに別物ですが、直感的に考えますと、1. あるクラスを継承するためには元になるクラス(スーパークラス)が先に定義されている必要がありますし、また、2. インスタンスを作る場合も同様に先にクラスが定義されている必要があります。これらの関係が混ざっていたとしても循環している場合は、どれが先に作られているのか(定義されているのか)が、わからなくなります。 Rubyですと、クラスを定義した後にクラスの定義を書き換える、ということがほぼ制限なしにできますので言語仕様としては実現可能ですが、他の言語ではどうなのだろう、と疑問に思ったわけです。説明が足りなくてすみませんでした。
otn

2020/08/26 07:34

なるほど。問題意識は理解できました。
guest

0

多くのオブジェクト指向言語でも何らかの循環構造はあります。

例えば Java では全てのクラスのスーパークラスは Object です。
しかし Object にはインスタンスメソッドとして getClass() があり、戻り値型は Class です。Ruby の Class とは違いこれは「クラスそのもの」ではなくクラスを参照するものでしかありませんが、Class は Object を継承しているので循環した定義です。
また Object には toString() もあり String も Object の子孫なのでやはり循環した定義です。

結局、オブジェクト指向のシステムそのものを実現する部分に関しては多少の循環定義はどうしてもせざるを得ず、仕方ないのではないでしょうか。

投稿2020/08/25 21:49

kagilinn

総合スコア354

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

.M.

2020/08/26 05:00

なるほど。どうもありがとうございます。意図的に循環させているわけではなくて、オブジェクト指向システムそのものが循環的な定義を要求するのだとしたら、個人的にですが非常に興味深いところです。 とあるサイトにJavaのClassはメタクラスだ、というような記事がありました。また自分でももう少し調べてみます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問