
Java道|多重継承の制限とObjectクラス
継承は自由に広がるようでいて、親クラスは1本だけ。
Object クラスを知ると、Javaのクラス構造が一本の大きな系譜として見えてきます。
Javaの継承では、親クラスから子クラスへ機能を受け継ぎながら、クラスを発展させていけます。
鬼滅の刃風にたとえると、鬼殺隊士という共通の型があり、そこから柱、継子、隠のように役割ごとのクラスが生まれていくイメージです。
ただし、Javaの継承には大切なルールがあります。
それは、1つのクラスが同時に複数のスーパークラスを持つことはできない ということです。
つまり、1つの子クラスが2つ以上の親クラスを同時に継承することはできません。
そして、もう1つ重要なルールがあります。
それが、スーパークラスを明示しないクラスは、自動的に Object クラスを親に持つ という仕組みです。
このため、Javaのすべてのクラスは、最終的に Object クラスにつながっています。
Object クラスは、Javaにおけるすべてのクラスの共通の親です。
鬼滅の刃風にたとえると、隊士、柱、日輪刀、任務書など、さまざまなクラスがあっても、Javaの世界ではすべて「オブジェクト」としての共通土台を持っているということです。
↓クリックすると拡大表示されます。

Javaでは複数のスーパークラスを同時に継承できない
まず押さえておきたいのは、Javaでは1つのクラスが複数のスーパークラスを同時に継承できないという点です。
たとえば、次のような2つのクラスがあるとします。
class DemonSlayer
{
}
class MedicalUnit
{
}DemonSlayer は鬼殺隊士を表すクラスです。
MedicalUnit は医療部隊を表すクラスです。
この2つを同時に親クラスとして持つクラスを作ることはできません。
// これはできない
class HealingPillar extends DemonSlayer, MedicalUnit
{
}Javaでは、クラスの継承で指定できる親クラスは1つだけです。
| 書き方 | Javaで可能か |
|---|---|
| class PillarSlayer extends DemonSlayer | 可能 |
| class HealingPillar extends DemonSlayer, MedicalUnit | 不可能 |
鬼滅の刃風にたとえると、1人の隊士クラスが「鬼殺隊士の型」と「医療部隊の型」を、同時に親として持つことはできないということです。
↓クリックすると拡大表示されます。

なぜ多重継承を制限しているのか
Javaがクラスの多重継承を許していない理由は、継承関係を分かりやすく保つためです。
もし1つのクラスが複数の親クラスを持てると、次のような問題が起こりやすくなります。
| 問題 | 内容 |
|---|---|
| 同じ名前のメソッドがある | どちらの親クラスのメソッドを使うのか迷う |
| 同じ名前のフィールドがある | どちらの値を参照するのか分かりにくい |
| 初期化の順番が複雑になる | どの親クラスから先に作るのか分かりにくい |
| 設計の見通しが悪くなる | クラスの責任範囲が曖昧になりやすい |
鬼滅の刃風にたとえると、1人の隊士が「水の呼吸の師匠」と「医療部隊の師匠」を同時に親として持ち、両方から同じ名前の奥義を受け継いだら、どちらの奥義を優先するのか分かりにくくなります。
Javaはこのような混乱を避けるため、クラスの親は1つだけにしています。
ただし、親から子へ、さらにその子へと縦につなげることはできます。
class DemonSlayer
{
}
class PillarSlayer extends DemonSlayer
{
}
class WaterPillarSlayer extends PillarSlayer
{
}この場合、WaterPillarSlayer は PillarSlayer を継承し、PillarSlayer は DemonSlayer を継承しています。
つまり、Javaでは複数の親を横に並べるのではなく、1本の系譜として縦につなげる形になります。
↓クリックすると拡大表示されます。

それでも複数の能力を持たせたいとき
クラスの多重継承はできません。
しかし、複数の能力や役割を持たせたい場面はあります。
そのときに使うのが インターフェイス です。
インターフェイスは、クラスの親そのものではなく、「この能力を持つ」という約束を表す仕組みです。
鬼滅の刃風にたとえると、隊士としての親クラスは1つでも、次のような能力の約束を複数持てるイメージです。
| 能力 | インターフェイス風の考え方 |
|---|---|
| 呼吸を使える | BreathingUser |
| 指揮できる | Leader |
| 治療できる | Healer |
| 索敵できる | Sensor |
たとえば、次のような形です。
class HealingPillar extends DemonSlayer implements BreathingUser, Healer
{
}この場合、HealingPillar は DemonSlayer を親クラスとして継承しています。
さらに、BreathingUser と Healer という能力の約束を持っています。
整理すると、次のようになります。
| しくみ | できること |
|---|---|
| クラスの継承 | 親クラスは1つだけ |
| インターフェイス | 複数の能力の約束を組み合わせられる |
つまり Java は、クラスの多重継承を避けつつ、必要な柔軟性はインターフェイスで補う仕組みを持っています。
スーパークラスを指定しないクラスはどうなるのか
ここからが、Object クラスの話です。
Javaでは、クラスを宣言するときにスーパークラスを指定しなかった場合、そのクラスは自動的に Object クラスを親に持ちます。
たとえば、次のように書いたとします。
class DemonSlayer
{
}このコードでは、extends を書いていません。
しかし、考え方としては次のような関係になります。
class DemonSlayer extends Object
{
}つまり、明示的に親クラスを書いていなくても、DemonSlayer は 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 |
このルールによって、Javaのすべてのクラスは最終的に Object クラスへつながります。
Objectクラスはなぜ「すべてのクラスの共通の親」なのか
Object クラスがすべてのクラスの共通の親と呼ばれる理由は、スーパークラスを明示しないクラスが自動的に Object を継承するからです。
鬼滅の刃風にたとえると、Object クラスは、隊士や道具などの種類が分かれる前にある、Javaオブジェクトとしての最も基本的な土台です。
たとえば、次のようなクラスがあるとします。
| クラス | 鬼滅の刃風の役割 |
|---|---|
| DemonSlayer | 鬼殺隊士 |
| PillarSlayer | 柱 |
| NichirinSword | 日輪刀 |
| MissionScroll | 任務書 |
| CrowMessenger | 鎹鴉 |
これらは見た目も役割も違います。
しかし、Javaのクラスとしては、どれも最終的に Object につながっています。
つまり、Object クラスは、
すべてのクラスが共通して受け継ぐ、Java世界の最上位の親
です。
継承の階層はどうつながっていくのか
Javaの継承関係は、上から下へと連なっていきます。
たとえば、次のような階層を考えます。
| 階層 | クラス例 | 鬼滅の刃風のイメージ |
|---|---|---|
| 最上位 | Object | すべての共通土台 |
| その下 | DemonSlayer | 鬼殺隊士 |
| さらに下 | PillarSlayer | 柱 |
| さらに下 | WaterPillarSlayer | 水柱 |
このとき、WaterPillarSlayer は WaterPillarSlayer 自身の特徴だけを持つわけではありません。
上の階層から、次のように受け継いでいます。
| 受け継ぐもの | 内容 |
|---|---|
| Object のメンバ | Javaオブジェクトとしての基本機能 |
| DemonSlayer のメンバ | 鬼殺隊士としての共通機能 |
| PillarSlayer のメンバ | 柱としての共通機能 |
| WaterPillarSlayer のメンバ | 水柱としての独自機能 |
つまり、下のクラスほど、上位クラスの性質を積み重ねながら、自分の個性を追加していく構造になります。
鬼滅の刃風にたとえると、水柱は水柱であると同時に、柱でもあり、鬼殺隊士でもあり、Java上では Object につながるオブジェクトでもあるということです。
図:多重継承の制限とObjectクラスの関係
↓クリックすると拡大表示されます。

この図が示していること
この図では、Javaの継承が Object クラスを頂点にした階層としてつながる様子を表しています。
Object クラスの下に DemonSlayer や NichirinSword があり、DemonSlayer の下に PillarSlayer、さらに WaterPillarSlayer が続いています。
この構造から、Javaのクラスは最終的に Object クラスへつながることが分かります。
また、右側の注意カードでは、1つのクラスが2つの親クラスを同時に継承できないことを示しています。
この図のポイントは次の2つです。
| ポイント | 内容 |
|---|---|
| Object クラス | すべてのクラスの共通の親 |
| 多重継承の制限 | クラスの親は1つだけ |
すべてのクラスはObjectクラスのメンバを持つ
Object クラスが共通の親であるということは、Javaのすべてのクラスが Object クラスのメンバを継承しているということです。
そのため、どんなクラスのオブジェクトでも、Object クラス由来の基本メソッドを持っています。
代表的なメソッドは次の3つです。
| メソッド | 機能 |
|---|---|
| equals(Object obj) | オブジェクトが引数と同じものかどうかを調べる |
| getClass() | オブジェクトのクラスを返す |
| toString() | オブジェクトを表す文字列を返す |
これらは、特定のクラスだけに用意されている特別なメソッドではありません。
DemonSlayer、PillarSlayer、NichirinSword、MissionScroll のように、どんなクラスでも最終的に Object につながるため、共通して使える基本機能です。
equals は何をするメソッドなのか
equals は、あるオブジェクトと、引数で渡したオブジェクトが同じものかどうかを調べるメソッドです。
たとえば、次のように使います。
slayer1.equals(slayer2);鬼滅の刃風にたとえると、
今見ている隊士と、比べようとしている隊士が同じ存在かどうかを確認する
ようなイメージです。
ただし、equals の意味はクラスによって作り直されることがあります。
Object 由来の equals は、基本的には同じオブジェクトを指しているかどうかを見る考え方です。
一方で、クラス側で equals をオーバーライドすれば、隊士番号や名前をもとに「同じ隊士かどうか」を判断するようにもできます。
| equals の使い方 | 内容 |
|---|---|
| Object 由来の equals | 同じオブジェクトかどうかを見る |
| オーバーライドした equals | クラスに合った同一性の判断をする |
getClass は何をするメソッドなのか
getClass は、そのオブジェクトがどのクラスに属しているかを返すメソッドです。
たとえば、次のように使います。
slayer1.getClass();鬼滅の刃風にたとえると、
この隊士は DemonSlayer なのか、PillarSlayer なのか、WaterPillarSlayer なのかを確認する
ような感覚です。
これは、ポリモーフィズムを考えるときにも大切です。
たとえば、次のように書いたとします。
DemonSlayer slayer1 = new PillarSlayer();この場合、変数の型は DemonSlayer です。
しかし、実際のオブジェクトは PillarSlayer です。
| 見るもの | 内容 |
|---|---|
| 変数の型 | DemonSlayer |
| 実際のオブジェクト | PillarSlayer |
| getClass() で分かるもの | 実体のクラス情報 |
getClass を使うと、見た目の変数型ではなく、実際のオブジェクトのクラス情報を確認できます。
toString は何をするメソッドなのか
toString は、オブジェクトを文字列で表したものを返すメソッドです。
そして、オブジェクトをそのまま出力しようとしたとき、この toString が呼び出されます。
たとえば、次のように書いたとします。
System.out.println(slayer1);このとき、内部的には slayer1 の toString() の結果が表示されます。
つまり toString は、
そのオブジェクトを文字でどう表すかを決めるメソッド
です。
鬼滅の刃風にたとえると、隊士が自分の情報を文字で名乗るための基本メソッドです。
何も準備しないとObjectクラスのtoStringが使われる
自分のクラスで toString を用意しなかった場合、Object クラスから継承した toString がそのまま使われます。
その場合、次のような形式の文字列が表示されることがあります。
DemonSlayer@1a2b3cこれはJavaとしては正しい表示です。
しかし、人間にとっては少し分かりにくいです。
| 表示 | 印象 |
|---|---|
| DemonSlayer@1a2b3c | 機械的な識別表示 |
| 名前: 水月、階級: 水柱 | 意味が分かりやすい表示 |
鬼滅の刃風にたとえると、隊士の紹介をしてほしいのに、名前や階級ではなく、識別番号だけが出てくるような感覚です。
このままでは、確認やデバッグには少し不便です。
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クラスを知ると継承の全体像が見える
Object クラスは、Javaの継承全体を支える土台です。
Object クラスを理解すると、次の流れが見えてきます。
| 流れ | 内容 |
|---|---|
| Javaのクラス継承は親クラス1つだけ | 多重継承はできない |
| 親をたどると最終的に Object に行き着く | すべてのクラスの共通の親 |
| すべてのクラスは Object の基本メソッドを持つ | equals、getClass、toString など |
| 必要に応じて基本メソッドを作り直せる | toString などをオーバーライドできる |
この見方ができると、Javaの継承はバラバラの親子関係ではなく、Object を最上位にした一本の大きな系譜として理解できます。
鬼滅の刃風にたとえると、隊士ごとに個性は違います。
柱、隠、継子、日輪刀、任務書など、クラスの種類も違います。
それでもJavaの世界では、すべてが Object という共通の土台につながっています。
図:Object の代表メソッドと共通機能
↓クリックすると拡大表示されます。

この図が示していること
この図では、Object クラスが持つ代表的なメソッドを整理しています。
Object クラスには、equals、getClass、toString のような基本メソッドがあります。
すべてのクラスは Object につながっているため、こうしたメソッドを共通して持ちます。
また、toString は自分のクラスでオーバーライドすると、分かりやすい文字列を返せるようになります。
| 状態 | 表示例 |
|---|---|
| Object 由来の toString をそのまま使う | DemonSlayer@1a2b3c |
| toString をオーバーライドする | 名前: 水月、階級: 水柱 |
この図から分かることは、Object のメソッドはただ受け継ぐだけではなく、必要に応じて自分のクラスらしく作り直せるということです。
鬼滅の刃風に多重継承とObjectクラスを整理する
Javaのクラスは、いろいろな隊士や道具の型のようなものです。
たとえば、次のようなクラスがあります。
| クラス | 鬼滅の刃風のイメージ |
|---|---|
| DemonSlayer | 鬼殺隊士 |
| PillarSlayer | 柱 |
| WaterPillarSlayer | 水柱 |
| NichirinSword | 日輪刀 |
| MissionScroll | 任務書 |
ただし、1つのクラスが複数の親クラスを同時に持つことはできません。
親クラスは1本だけです。
その一方で、どんなクラスも上までたどれば Object クラスに行き着きます。
だから、どのクラスも次の基本機能を共通に持っています。
| Object のメソッド | 鬼滅の刃風のイメージ |
|---|---|
| equals | 同じ隊士や道具か確認する |
| getClass | 実際の型を確認する |
| toString | 自分の情報を文字で名乗る |
つまり、Javaの継承は、
親クラスは1本だけでつながり、その最上位には Object がある
という構造です。
この内容で押さえておきたいポイント
| ポイント | 内容 |
|---|---|
| 多重継承 | Javaでは1つのクラスが複数のスーパークラスを同時に継承できない |
| 単一継承 | クラスの直接の親は1つだけ |
| 継承階層 | 親から子へ、さらにその子へと縦につながる |
| インターフェイス | 複数の能力の約束を組み合わせられる |
| Object クラス | すべてのクラスの共通の親 |
| extends を書かないクラス | 自動的に Object を親に持つ |
| equals | オブジェクト同士を比較する |
| getClass | 実際のクラス情報を返す |
| toString | オブジェクトを文字列で表す |
多重継承の制限を知ると、Javaがクラスの親子関係をシンプルに保っていることが分かります。
そして Object クラスを知ると、Javaのすべてのクラスが共通の土台につながっていることが見えてきます。
この2つを合わせて理解すると、Javaの継承は「自由に枝分かれする複雑な網」ではなく、Object を頂点とした一本の系譜として整理できます。
