Javaの非常勤講師をやっていますが、訓練生さんから以下の質問をいただきました。

java.lang.Objectクラス(あらゆるクラスの親クラス)が具象クラス(抽象クラスでない)として定義されているのでインスタンス化できる。しかし、これはオブジェクト指向の思想に反するのではないか?

確かにそうだなと思っていろいろ調べ始めたら、実はけっこう根深い問題だということが発覚し、
しかも、あまり日本語の参考文献がなかったので、まとめてみることにしました。

なぜ「オブジェクト指向の思想に反する」のか

オブジェクト指向には、「抽象的なものはインスタンス化すべきでない」という思想があります。
例えば「Vehicle(乗り物)」クラスがあったとき、
「Vehicleの実体」というのは現実世界にあり得ない。
だから、Vehicleクラスを継承してもらって、
その先(たとえば「Carクラス」など)ではインスタンス化する。

他のたとえだと、例えば食堂にいって「うどん」とか「そば」はあるけど「麺」ってメニューはないよね。みたいな感じで、「概念的」「カテゴリ的」なクラスは、インスタンス化されるのが不自然だという考え方です。

が、Objectクラスというのはいわば「最も抽象的なものを表すクラス」であり、
にも関わらず、インスタンス化可能であるように定義されているのです。

Objectクラスは抽象メソッドを持たない

まず、Objectクラスは
こちらのAPIreferenceを参照していただければ分かるように、
抽象メソッドを持っていません。まぁでもこれは、別に
「概念自体が抽象的であること」とは関係がないのです。
継承ツリーをどんどん上にたどった結果、
抽象メソッドすら無くなってしまう、ということはある話なので。

でも、それとは関係なく、やはり「Objectの実体」というのはどうも違和感があります。

抽象メソッドを持たない抽象クラスは定義できる

インスタンス化できないクラス、すなわち抽象クラスは、
メンバとして抽象メソッドを持たなくても定義することが出来ます。
具体的には、以下のようにクラスの宣言を行えばよいだけです。

abstract class Hoge{
 //中身は全部具象メソッド。
}

僕の直感としては、Objectクラスってこうなっているべきなのではないか?
と思ってしまうのですが、Objectクラスに「abstract」はついていません。

Objectクラスをabstractにすると、それを継承したすべてのクラスがabstractになってしまうから?

表題のような疑問をちょっと抱いてしまったのですが、それは大嘘でした。
なぜなら、Objectを継承し、継承先でabstractを外せば具象クラスになるからです。

paiza.ioで実験しました。クラスBは抽象クラスAを継承した具象クラスになっています。

paiza.ioで実験しました。クラスBは抽象クラスAを継承した具象クラスになっています。

となると、なおさら「なぜObjectが具象クラスになっているのか」がわからなくなってきます。

かなり議論されていた

いろいろ考えてtwitterなんかにも疑問を垂れ流していたら、
とある方がものすごく丁寧に疑問に答えてくださいました。

なんと、この問題はいまだに議論の対象になっているようです。
最初にツイートで教えていただいた海外サイトでの議論を見てみると、

質問者▶Objectクラスがインスタンス化可能なのはなぜ?

回答者
▶逆に、Objectクラスを抽象にするメリットはなに?
▶Objectインスタンスが役に立つことがたくさんある。
▶具象にするメリットはあれど、抽象にするメリットはない。

意外と、こんなかんじ。ビシっとした概念的にしっくりする説明はないようで、
「色々役に立つんだから具象クラスでいいじゃない」くらいの雰囲気のようです。びっくり。
でもやっぱり「いやでも抽象クラスのほうがいいんじゃないの?」という人も多いみたい。

とりあえず、こんな感じでまとめてみました。
ご回答いただいた皆さんに深く深く感謝です。ありがとうございますm(_ _)m