
Java道|Objectクラスと継承のしくみ
どんなクラスも、たどっていけば Object に行き着く。
Object クラスを知ると、Javaの継承がひとつの大きな階層としてつながっていることが見えてきます。
Javaでは、クラスを継承によって広げていけます。
親クラスであるスーパークラスを土台にして、子クラスであるサブクラスを作ります。
さらに、そのサブクラスをもう一段階拡張して、新しいサブクラスを作ることもできます。
このように、クラス同士が親子関係でつながっていく構造を クラスの階層 といいます。
鬼滅の刃風にたとえると、まず鬼殺隊士という共通の土台があります。
そこから柱、隠、継子のように、役割ごとのクラスが分かれていくイメージです。
さらに、柱の中でも水柱、炎柱、風柱のように、もう一段階細かいクラスへ広がることも考えられます。
ただし、Javaの継承には大切なルールがあります。
| できること・できないこと | 内容 |
|---|---|
| 1つのスーパークラスから複数のサブクラスを作る | できる |
| サブクラスをさらに拡張する | できる |
| 1つのクラスが複数のスーパークラスを同時に継承する | できない |
| スーパークラスを書かないクラスが Object につながる | 自動的につながる |
特に重要なのが、スーパークラスを明示しないクラスは、自動的に Object クラスを親に持つ というルールです。
つまり、Javaで作るすべてのクラスは、最終的には Object クラスにつながっています。
Object クラスは、Javaのあらゆるクラスにとっての共通の親です。
クラスの階層を作るとはどういうことか
Javaでは、1つのスーパークラスをもとにして、複数のサブクラスを作れます。
鬼滅の刃風にたとえると、まず DemonSlayer という鬼殺隊士の共通クラスがあるとします。
そこから、次のようなサブクラスを作れます。
| スーパークラス | サブクラスの例 | 意味 |
|---|---|---|
| DemonSlayer | PillarSlayer | 柱の隊士 |
| DemonSlayer | KakushiMember | 隠の隊士 |
| DemonSlayer | TsugukoSlayer | 継子の隊士 |
このように、1つの親クラスから複数の子クラスへ分かれていくことができます。
さらに、PillarSlayer を土台にして、もう一段階細かいクラスを作ることもできます。
| 上位クラス | 下位クラス | 意味 |
|---|---|---|
| DemonSlayer | PillarSlayer | 柱の基本クラス |
| PillarSlayer | WaterPillarSlayer | 水柱 |
| PillarSlayer | FlamePillarSlayer | 炎柱 |
このように、親から子へ、さらにその子へとつながっていく構造が、クラスの階層です。
鬼滅の刃風にたとえると、鬼殺隊士という大きな土台から、柱という特別な役割が生まれ、その中でさらに水柱や炎柱のような個性が分かれていく流れです。
↓クリックすると拡大表示されます。

サブクラスをさらに拡張すると何が起こるのか
サブクラスをさらに拡張した場合、新しく作ったクラスは、直前の親クラスだけでなく、さらに上のクラスの性質も受け継ぎます。
たとえば、次のような関係を考えます。
class DemonSlayer
{
}
class PillarSlayer extends DemonSlayer
{
}
class WaterPillarSlayer extends PillarSlayer
{
}この場合、WaterPillarSlayer は PillarSlayer を継承しています。
そして、PillarSlayer は DemonSlayer を継承しています。
つまり、WaterPillarSlayer は次の要素を持つことになります。
| 受け継ぐもの | 内容 |
|---|---|
| WaterPillarSlayer 自身の特徴 | 水柱としての独自要素 |
| PillarSlayer の特徴 | 柱としての要素 |
| DemonSlayer の特徴 | 鬼殺隊士としての共通要素 |
| Object の特徴 | Javaオブジェクトとしての基本機能 |
継承は、直前の親だけで止まるわけではありません。
階層を上にたどって、親、その親、さらにその親の性質がつながっていきます。
鬼滅の刃風にたとえると、水柱は水柱としての個性を持っています。
同時に、柱でもあり、鬼殺隊士でもあり、Java上では Object につながるオブジェクトでもあります。
Javaでは複数のスーパークラスを同時に継承できない
Javaでは、1つのクラスが複数のスーパークラスを同時に継承することはできません。
たとえば、次のような2つの親クラスがあるとします。
class DemonSlayer
{
}
class MedicalUnit
{
}この2つを同時に継承して、次のように書くことはできません。
// これはできない
class HealingPillar extends DemonSlayer, MedicalUnit
{
}Javaのクラス継承では、親クラスは1つだけです。
鬼滅の刃風にたとえると、1人の隊士クラスが「鬼殺隊士の型」と「医療部隊の型」を、両方とも親クラスとして同時に持つような形は作れません。
なぜなら、複数の親クラスを同時に持つと、同じ名前のメソッドやフィールドがあった場合に、どちらを優先するのかが複雑になりやすいからです。
Javaはここをシンプルに保つため、クラスの継承は1本の親だけにしています。
| しくみ | Javaでの扱い |
|---|---|
| クラスの継承 | 親クラスは1つだけ |
| 複数の親クラスを同時に継承 | できない |
| サブクラスをさらに継承 | できる |
それでも共通の能力を増やしたいとき
Javaでは、クラスの継承で複数の親クラスを持つことはできません。
しかし、複数の能力や役割を持たせたい場合には、インターフェイスを使えます。
たとえば、鬼滅の刃風に考えると、隊士には次のような能力があります。
| 能力 | インターフェイス風の考え方 |
|---|---|
| 呼吸を使える | BreathingUser |
| 任務を指揮できる | Leader |
| 仲間を補助できる | Supporter |
クラスとしての親は1つだけでも、能力の約束は複数組み合わせられます。
class WaterPillarSlayer extends DemonSlayer implements BreathingUser, Leader
{
}このように考えると、次の違いが見えてきます。
| しくみ | できること |
|---|---|
| クラスの継承 | 親クラスは1つだけ |
| インターフェイス | 能力の約束を複数組み合わせられる |
今回の中心は Object クラスと継承ですが、Javaが「クラスの親は1つだけ」にしている一方で、「役割や能力はインターフェイスで複数持てる」ようにしていることも、あわせて覚えておくと整理しやすいです。
Objectクラスはすべてのクラスの共通の親
ここからが今回の中心です。
Javaでは、クラスを宣言するときにスーパークラスを指定しない場合、そのクラスは自動的に Object クラスを親に持ちます。
たとえば、次のように書いたとします。
class DemonSlayer
{
}extends を書いていません。
しかし、考え方としては次のような関係になります。
class DemonSlayer extends Object
{
}つまり、何も書いていなくても、DemonSlayer は Object クラスの子クラスです。
このルールがあるため、Javaのクラスは最終的にすべて Object クラスにつながります。
| 書いたクラス | 実際の継承関係の考え方 |
|---|---|
| class DemonSlayer | DemonSlayer extends Object |
| class PillarSlayer extends DemonSlayer | PillarSlayer extends DemonSlayer extends Object |
| class WaterPillarSlayer extends PillarSlayer | WaterPillarSlayer extends PillarSlayer extends DemonSlayer extends Object |
Object クラスは、Javaのすべてのクラスにとっての一番上の親です。
鬼滅の刃風に考える Object クラス
鬼滅の刃風にたとえると、Object クラスは「すべての隊士や道具が、Javaの世界で共通に持っている最も基本の型」です。
鬼殺隊士、柱、隠、刀、任務書など、いろいろなクラスを作れるとします。
それぞれ見た目も役割も違います。
| クラス | 鬼滅の刃風の役割 |
|---|---|
| DemonSlayer | 鬼殺隊士 |
| PillarSlayer | 柱 |
| NichirinSword | 日輪刀 |
| MissionScroll | 任務書 |
しかし、Javaのクラスとしては、どれも最終的に Object につながります。
つまり Object クラスは、鬼滅の刃風に言えば、
隊士や道具などの種類が分かれる前にある、Javaオブジェクトとしての共通土台
のような存在です。
Objectクラスにつながる階層の見方
Object クラスを一番上に置いて、クラスの階層を整理すると分かりやすくなります。
| 階層 | 例 |
|---|---|
| 最上位の共通の親 | Object |
| その子クラス | DemonSlayer |
| さらにその子クラス | PillarSlayer |
| さらにその子クラス | WaterPillarSlayer |
このような階層になっている場合、WaterPillarSlayer は WaterPillarSlayer 自身の特徴だけを持っているわけではありません。
次のように、上位クラスの性質も積み重ねています。
| クラス | 受け継ぐもの |
|---|---|
| Object | Javaオブジェクトとしての基本機能 |
| DemonSlayer | 鬼殺隊士としての共通機能 |
| PillarSlayer | 柱としての共通機能 |
| WaterPillarSlayer | 水柱としての独自機能 |
このように見ると、Javaの継承はバラバラの親子関係ではなく、Object を頂点にした大きな階層としてつながっていることが分かります。
図:Objectクラスを頂点にした継承階層
↓クリックすると拡大表示されます。

この図が示していること
この図では、Object クラスが一番上にあり、その下に DemonSlayer や NichirinSword のようなクラスがつながっています。
DemonSlayer の下には PillarSlayer、さらにその下に WaterPillarSlayer が続いています。
この形から、下のクラスほど上のクラスの性質を積み重ねて受け継いでいることが分かります。
また、右下の注意カードでは、1つのクラスが複数のスーパークラスを同時に継承できないことも示しています。
つまりこの図は、次の2つを表しています。
| ポイント | 内容 |
|---|---|
| Object はすべてのクラスの共通の親 | 何も extends しないクラスも Object につながる |
| Javaのクラス継承は単一継承 | 1つのクラスが持てる直接の親クラスは1つだけ |
Javaのすべてのクラスは Object のメンバを持つ
Object クラスが共通の親であるということは、Javaのすべてのクラスが Object クラスのメンバを継承しているということです。
これはとても大事です。
なぜなら、Object クラスが持っている基本メソッドを、どんなクラスのオブジェクトでも使えるからです。
代表的なメソッドには、次のようなものがあります。
| メソッド | 役割 |
|---|---|
| equals(Object obj) | 引数のオブジェクトと同じかどうかを調べる |
| getClass() | オブジェクトのクラス情報を返す |
| toString() | オブジェクトを表す文字列を返す |
これらは、特定のクラスだけのものではありません。
Javaのあらゆるクラスが Object につながっているため、共通して使える基本メソッドです。
equals の役割
equals は、あるオブジェクトが、引数として渡されたオブジェクトと同じかどうかを調べるためのメソッドです。
鬼滅の刃風にたとえると、
この隊士と、比較している隊士は同じ存在なのか
を確認するようなイメージです。
slayer1.equals(slayer2);このように使うと、slayer1 と slayer2 を比較できます。
ただし、equals の動きはクラスによってオーバーライドされることがあります。
何もオーバーライドしていない場合は、基本的には同じオブジェクトを指しているかどうかを見る考え方になります。
一方で、クラス側で equals を作り直せば、名前やIDなどをもとに「同じ隊士かどうか」を判断するようにもできます。
| 使い方 | 考え方 |
|---|---|
| Object 由来の equals | 同じオブジェクトかどうかを見る |
| オーバーライドした equals | クラスに合った同一性の判断をする |
鬼滅の刃風にたとえると、ただ同じ場所にいるかではなく、隊士番号や名前などをもとに同一人物か判断するように作り直せる、ということです。
getClass の役割
getClass は、そのオブジェクトがどのクラスに属しているかを返すメソッドです。
鬼滅の刃風にたとえると、
このオブジェクトは DemonSlayer なのか、PillarSlayer なのか、WaterPillarSlayer なのか
を確認するようなものです。
slayer1.getClass();このメソッドを使うと、変数の型ではなく、実際のオブジェクトのクラス情報を確認できます。
これは、ポリモーフィズムを学んだあとだと理解しやすいです。
たとえば、次のようなコードを考えます。
DemonSlayer slayer1 = new PillarSlayer();この場合、変数の型は DemonSlayer です。
しかし、実体は PillarSlayer です。
getClass() を使うと、実際のオブジェクトのクラス情報を確認できます。
| 見るもの | 内容 |
|---|---|
| 変数の型 | DemonSlayer |
| 実際のオブジェクト | PillarSlayer |
| getClass() で分かるもの | 実体のクラス情報 |
鬼滅の刃風にたとえると、名簿上は鬼殺隊士として扱っていても、実際には柱であることを確認できるような感覚です。
toString の役割
Object クラスのメソッドの中でも、特に大切なのが toString です。
toString は、オブジェクトを文字列として表したものを返すメソッドです。
たとえば、オブジェクトを System.out.println で表示するとき、内部では toString の結果が使われます。
System.out.println(slayer1);このように書いた場合、slayer1 の toString() が呼ばれ、その戻り値が表示されます。
つまり、toString は、
そのオブジェクトを文字列でどう表すか
を決めるメソッドです。
鬼滅の刃風にたとえると、隊士が自分の情報を文字で名乗るための基本メソッドです。
Objectから受け継いだ toString をそのまま使うとどうなるか
何も準備しないままオブジェクトを表示すると、Object クラスから受け継いだ toString がそのまま使われます。
その場合、次のような形式の文字列が表示されることがあります。
DemonSlayer@1a2b3cこれは Java としては正しい表示です。
ただし、人間にとってはあまり分かりやすくありません。
| 表示 | 分かること |
|---|---|
| DemonSlayer@1a2b3c | クラス名と識別用の情報らしきもの |
| 名前: 水月, 階級: 水柱 | オブジェクトの意味ある情報 |
鬼滅の刃風にたとえると、隊士を紹介してほしいのに、名前や階級ではなく、管理番号のようなものだけが表示される感覚です。
確認や学習には少し不便です。
toString をオーバーライドすると便利になる
そこで便利なのが、toString のオーバーライドです。
自分のクラスで toString を作り直すと、そのオブジェクトを表示したときに、意味のある文字列を返せるようになります。
たとえば、DemonSlayer クラスなら、次のようにできます。
class DemonSlayer
{
private String name;
private String rank;
public DemonSlayer(String name, String rank)
{
this.name = name;
this.rank = rank;
}
public String toString()
{
return "名前: " + name + "、階級: " + rank;
}
}このように toString をオーバーライドしておくと、次のように表示できます。
DemonSlayer slayer1 = new DemonSlayer("水月", "水柱");
System.out.println(slayer1);表示イメージは次のようになります。
名前: 水月、階級: 水柱これは、Object から受け継いだ toString を、DemonSlayer クラスに合うように作り直している状態です。
鬼滅の刃風にたとえると、ただの管理番号ではなく、隊士が自分の名前や階級をきちんと名乗れるようにするイメージです。
toString はなぜ便利なのか
toString をオーバーライドすると、デバッグや表示がとても分かりやすくなります。
たとえば、オブジェクトの中身を確認したいときに、意味のある情報が表示されるからです。
| toString をそのまま使う場合 | toString をオーバーライドした場合 |
|---|---|
| DemonSlayer@1a2b3c のような表示 | 名前や階級など意味のある表示 |
| 中身が分かりにくい | 状態を確認しやすい |
| 学習中に混乱しやすい | オブジェクトの内容をつかみやすい |
toString は、Javaのクラスでとてもよく使うオーバーライド対象のひとつです。
図:Object の代表メソッドと toString のオーバーライド
↓クリックすると拡大表示されます。

この図が示していること
この図では、Object クラスが持つ代表的なメソッドと、toString をオーバーライドする意味を整理しています。
Object クラスには、equals、getClass、toString のような基本メソッドがあります。
すべてのクラスは Object につながっているため、こうしたメソッドを共通に持ちます。
右側では、DemonSlayer クラスが toString を自分用に作り直しています。
その結果、何も準備していない場合は DemonSlayer@1a2b3c のような表示になりやすいところを、名前や階級が分かる表示にできます。
この図から分かることは、Object のメソッドはただ受け継ぐだけでなく、必要に応じて自分のクラスらしくオーバーライドできるということです。
なぜ Object クラスを知ることが大切なのか
Object クラスは、普段のコードで明示的に extends Object と書くことが少ないため、最初は少し地味に感じるかもしれません。
しかし、Javaの継承を理解するうえではとても重要です。
理由は、次のとおりです。
| 理由 | 内容 |
|---|---|
| すべてのクラスが Object につながる | Javaの継承階層の根になる |
| 基本メソッドを共通で持つ | equals、getClass、toString などが使える |
| オーバーライドの理解につながる | toString などを自分用に作り直せる |
| ポリモーフィズムの土台になる | Object 型でさまざまなオブジェクトを扱える考え方につながる |
Object クラスを知ると、Javaのクラスが完全にバラバラに存在しているのではなく、1つの大きな階層としてつながっていることが分かります。
Object 型でいろいろなオブジェクトを扱える
Object はすべてのクラスの親なので、Object 型の変数には、いろいろなクラスのオブジェクトを入れられます。
Object obj1 = new DemonSlayer("水月", "水柱");
Object obj2 = new MissionScroll();
Object obj3 = new NichirinSword();これは、DemonSlayer も MissionScroll も NichirinSword も、すべて Object の一種だからです。
鬼滅の刃風にたとえると、隊士、任務書、日輪刀のように種類が違っても、Javaの世界ではすべて「オブジェクト」として扱えるということです。
ただし、Object 型として扱う場合、呼び出せるのは基本的に Object にあるメソッドです。
そのクラス独自のメソッドをそのまま呼びたい場合は、型を意識する必要があります。
この考え方は、スーパークラス型でサブクラスを扱うポリモーフィズムともつながります。
鬼滅の刃風に Object クラスを整理する
Javaのクラスは、見た目にはそれぞれ別の存在です。
鬼滅の刃風にたとえると、次のようにさまざまなクラスがあります。
| クラス | 役割 |
|---|---|
| DemonSlayer | 鬼殺隊士 |
| PillarSlayer | 柱 |
| WaterPillarSlayer | 水柱 |
| NichirinSword | 日輪刀 |
| MissionScroll | 任務書 |
しかし、どれも最終的には Object クラスにつながっています。
そのため、どのクラスも Object 由来の基本メソッドを持っています。
| Object のメソッド | 鬼滅の刃風のイメージ |
|---|---|
| equals | 同じ隊士や道具か確認する |
| getClass | 何のクラスの実体か調べる |
| toString | 自分の情報を文字で名乗る |
Object クラスは、
すべてのクラスが最初に受け継いでいる共通の親
です。
この考え方が分かると、Javaの継承は、単なる親子関係の集まりではなく、Object を頂点にしたひとつの大きな仕組みとして見えてきます。
この内容で押さえておきたいポイント
| ポイント | 内容 |
|---|---|
| クラスの階層 | 親から子へ、さらにその子へとつながる構造 |
| サブクラスの拡張 | 上位クラスのメンバも積み重ねて受け継ぐ |
| Javaの単一継承 | 1つのクラスが直接継承できる親クラスは1つだけ |
| Object クラス | すべてのクラスの共通の親 |
| extends を書かないクラス | 自動的に Object を親に持つ |
| equals | オブジェクト同士を比較する基本メソッド |
| getClass | 実際のクラス情報を確認するメソッド |
| toString | オブジェクトを文字列で表すメソッド |
| toString のオーバーライド | オブジェクトを分かりやすく表示できる |
Object クラスを理解すると、Javaのクラスがすべて共通の土台につながっていることが分かります。
そして、equals、getClass、toString のような基本メソッドがどのクラスでも使える理由も見えてきます。
特に toString は、自分のクラスらしくオーバーライドすることで、オブジェクトの状態を分かりやすく表示できる便利なメソッドです。
