自作クラスの親クラスがModuleではなく、Objectになる理由
- 評価
- クリップ 0
- VIEW 871
自作クラスの親クラスがModule
ではなく、Object
になる理由をお聞きしたいです。
下記のコードを書いたとします。
class MySuper
end
class MySub
end
この時、superclass
で親クラスを辿ると下記のような関係になります。
# Object
# ↑ ↑
# MySuper Module
# ↑ ↑
# MySub Class
MySuper
やMySub
は定数で、Class
クラスのインスタンスを格納しているとすると、下記のようになると思いました。
Object
↑
Module
↑
Class
↑
MySuper
↑
MySub
このような継承関係にならない理由は何故でしょうか?
ご回答、よろしくお願い致します。
追記
現在の私の理解を、図に表してみました。
-
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
クリップを取り消します
-
良い質問の評価を上げる
以下のような質問は評価を上げましょう
- 質問内容が明確
- 自分も答えを知りたい
- 質問者以外のユーザにも役立つ
評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。
質問の評価を上げたことを取り消します
-
評価を下げられる数の上限に達しました
評価を下げることができません
- 1日5回まで評価を下げられます
- 1日に1ユーザに対して2回まで評価を下げられます
質問の評価を下げる
teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。
- プログラミングに関係のない質問
- やってほしいことだけを記載した丸投げの質問
- 問題・課題が含まれていない質問
- 意図的に内容が抹消された質問
- 過去に投稿した質問と同じ内容の質問
- 広告と受け取られるような投稿
評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
checkベストアンサー
+1
親クラスを指定しないクラスの親はObjectクラスです。
おそらく、「Classクラス」の親クラスがModuleクラスであることと混同されているのではないでしょうか。
「クラス」と「Classクラス」は別物です。
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
0
うーん、整理して説明するのが難しいな・・・
まず、大前提として、Rubyでは全てがオブジェクトです。Classもオブジェクトです。そして、全てのオブジェクトは何らかのクラスのインスタンスです。ClassもClassのインスタンスです。ここまでいいですか?
さて、class構文でクラスを作成していますが、
class MyClass
end
と
class MyClass < Object
end
と
MyClass = Class.new
と
MyClass = Class.new(Object)
はほぼ同じです。厳密には前半二つと後半二つでは作られ方に微妙な違いがあるのですが、結果的に作られている物は同じです。
まず、最初の二つを見てください。Rubyでは<
を用いて親クラスを指定しなかった場合、< Object
とObjectが親クラスに指定された物と見なされます。どうしてそうなるかは仕様というしかありません。逆に言えば、クラスを作るときは本当は必ず親クラスの指定が必要なんだけど、< Object
の場合は省略しても良いということもできます。なので、目には見えない< Object
が本当は存在するため、Objectが親クラスになります。
次に、前半二つと後半二つの関係ですが、class構文は言ってみればClass.newの特別な書き方で、Classのインスタンスを作るということわかりやすく書けるようにしていると言えます。実質A = Array.new
とか書くのと変わりません。module構文も同じで、Module.newをしているだけです。なんら特別なことはしていません。後半二つの間の違いは親クラスの指定ですが、こちらもclass構文と同じで、省略したらObjectを指定したと見なされます。
そこで気付いたと思いますが、そう、class構文で作ったクラスもまた、ただの定数です。Class
もまたただの定数にすぎません。クラスになっている物もすべて他の定数と同じように扱われ、それ以上でもそれ以下でもありません。ただそれらがClassのインスタンスであり、(削除をしていない限り)new
メソッドを呼び出すとそのインスタンスを作るという動きになっているだけにすぎません。
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 88.09%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる
2016/04/26 12:28
> 親クラスを指定しないクラスの親はObjectクラスです。
Classクラスの場合は、
class Class < Module; end
のようになっているから、Classクラスの親クラスはModuleクラスなのでしょうか?
> 「クラス」と「Classクラス」は別物です。
クラスを作っているのが、Classクラスだと思っております。下記のnewのレシーバーのClassは、Classクラスだと思っていのですが、違うのでしょうか?
MyClass = Class.new
2016/04/26 12:55
そうですね。
> 下記のnewのレシーバーのClassは、Classクラスだと思っていのですが、違うのでしょうか?
違いません。その通りです。
Classクラスのインスタンスが作られ、MyClassに代入されます。
この質問が出ると言うことは、「クラス⇔インスタンス」の関係と「親クラス⇔子クラス」の関係の整理が付いていないような気がします。
「クラス⇔インスタンス」・・・・・Class⇔MyClass
「親クラス⇔子クラス」・・・・・・Object⇔MyClass
2016/04/26 21:11
私が理解している関係を図にして、本文トピックに追記として追加しました。どこかが間違っているのでしょうか?
自作クラスの親クラスがClassでも、Moduleでもなく、Objectになる理由がまだわかりません。
お手数おかけしますが、ご回答いただければ幸いです。
2016/04/26 23:05
> 自作クラスの親クラスがClassでも、Moduleでもなく、Objectになる理由がまだわかりません。
クラスをそういう風に決めているというか、親を指定しないクラスはそのままでは親がないので、すべてのクラスの親としてObjectというクラスを設けたと言うことです。
逆に、何故ClassやModuleになると思うのでしょう?
「xがyのインスタンスである」と「xの親クラスがyである」を混同しているとしか思えないです。
2016/05/03 16:36
もう一度自分でコードを書いて整理し、納得することができました。
http://qiita.com/mitsuru793/items/1a37c82dcb60b31dfdc8
> 逆に、何故ClassやModuleになると思うのでしょう?
ClassやModuleに追加したメソッドが自作クラスでも使えることから混同していました。しかし、これは追加したインスタンスメソッドがクラスメソッドとして使える点で、継承とは違います。使えるようになるのは`Class`クラスを通してクラス自体の仕様を変えていたからですよね。
otnさんの下記のご指摘をきっかけに解決することができました。大変助かりました。本当にありがとうございました。
> この質問が出ると言うことは、「クラス⇔インスタンス」の関係と「親クラス⇔子クラス」の関係の整理が付いていないような気がします。
> 「クラス⇔インスタンス」・・・・・Class⇔MyClass
> 「親クラス⇔子クラス」・・・・・・Object⇔MyClass