
Java道|11章のまとめ
継承を知ると、クラスの関係がつながり、役割が広がり、コードはもっと強くなる。
11章は、Javaオブジェクト指向の「親から子へ受け継ぐ力」を学ぶ章です。
11章では、Javaのオブジェクト指向の中でも、とても重要な 継承 を中心に学びました。
継承は、すでに作ってあるクラスを土台にして、新しいクラスを効率よく作るためのしくみです。
まったくゼロから作り直すのではなく、親クラスの力を受け継ぎながら、必要な特徴だけを子クラスに追加できます。
鬼滅の刃風にたとえると、まず DemonSlayer クラス という鬼殺隊士の共通の型があります。
そこから、より特別な役割を持つ PillarSlayer クラス や、水柱を表す WaterPillarSlayer クラス を作っていくようなイメージです。
親クラスに共通部分をまとめ、子クラスでは個性を加える。
この考え方が、11章全体を通して大切な流れでした。
11章で扱った内容は、単に extends の書き方だけではありません。
| 学んだ内容 | 役割 |
|---|---|
| 継承 | 親クラスの機能を子クラスへ受け継ぐ |
| スーパークラスとサブクラス | 親と子の関係を整理する |
| protected | 子クラスから使えるメンバを作る |
| オーバーライド | 親のメソッドを子クラス用に作り直す |
| ポリモーフィズム | 同じ呼び出しで実体ごとに違う動きをさせる |
| オーバーロードとの違い | 同名メソッドの使い分けを整理する |
| final | 変更・継承・上書きを制限する |
| Object クラス | すべてのクラスの共通の親 |
| toString() | オブジェクトを文字列で表す |
| equals() | オブジェクトが同じかどうか調べる |
| getClass() | オブジェクトの実体のクラス情報を調べる |
つまり11章は、既存のクラスをどう活かし、どう広げ、どこを守り、どう共通化するかを学ぶ章です。
ここが見えてくると、Javaのオブジェクト指向は単なる文法ではなく、クラス設計そのものに関わる考え方だと分かってきます。
継承は親の力を受け継いで新しいクラスを作るしくみ
11章の中心にあるのは、継承です。
継承では、スーパークラスをもとにしてサブクラスを作ります。
サブクラスは、スーパークラスのフィールドやメソッドを受け継ぎながら、自分に必要な新しい機能を追加できます。
鬼滅の刃風にたとえると、DemonSlayer クラスには鬼殺隊士としての共通情報があります。
| DemonSlayer クラスの共通要素 | 内容 |
|---|---|
| name | 隊士の名前 |
| rank | 階級 |
| show() | 隊士情報を表示する |
| setSlayer() | 名前や階級を設定する |
そこから PillarSlayer クラスを作る場合、DemonSlayer の共通要素を受け継ぎます。
そのうえで、柱だけが持つ担当区域や特別な表示機能を追加できます。
| PillarSlayer クラスで追加する要素 | 内容 |
|---|---|
| area | 担当区域 |
| setArea() | 担当区域を設定する |
| show() の作り直し | 柱らしい情報表示にする |
このように、親クラスには共通部分を書き、子クラスには個別の特徴を書きます。
同じようなコードを何度も書かなくて済むので、継承はコードの再利用に役立ちます。
サブクラスはスーパークラスのメンバを受け継ぐ
継承を使うと、サブクラスはスーパークラスのメンバを受け継げます。
たとえば、DemonSlayer クラスに show() がある場合、PillarSlayer クラスはその show() を使えます。
PillarSlayer 側に同じ処理をもう一度書かなくてもよいのが大きなポイントです。
鬼滅の刃風にたとえると、柱は柱としての特別な役割を持っています。
しかし、柱である前に鬼殺隊士でもあります。
そのため、鬼殺隊士としての名前や階級、基本表示の機能を受け継げます。
| 考え方 | 鬼滅の刃風のイメージ |
|---|---|
| スーパークラス | 鬼殺隊士の共通設計 |
| サブクラス | 柱などの特別な隊士 |
| 継承 | 鬼殺隊士としての基本を受け継ぐ |
| 追加 | 柱としての特徴を加える |
このように、継承は「共通部分を親にまとめ、違いだけを子に書く」ためのしくみです。
protected は親子関係の中で使いやすいアクセス指定
11章では、メンバへのアクセス範囲も学びました。
スーパークラスの private メンバには、サブクラスから直接アクセスできません。
一方で、protected メンバなら、サブクラスから直接アクセスできます。
| アクセス修飾子 | サブクラスから直接アクセスできるか | 役割 |
|---|---|---|
| private | できない | そのクラス内部だけで守る |
| protected | できる | 子クラスにも使わせる |
| public | できる | 外部にも公開する |
鬼滅の刃風にたとえると、DemonSlayer クラスが持つ情報の中には、親クラスだけで管理したいものもあります。
一方で、PillarSlayer クラスにも使わせたい情報もあります。
たとえば、name や rank を PillarSlayer の show() で表示したいなら、protected にしておくと扱いやすくなります。
| 情報 | private が向く場合 | protected が向く場合 |
|---|---|---|
| name | 親クラスだけで厳密に管理したい | 子クラスでも表示したい |
| rank | 外部や子から直接触らせたくない | 子クラスの処理でも使いたい |
| area | PillarSlayer 内だけで使う | 親子で共有する必要がない |
protected は、カプセル化を完全に崩すものではありません。
親子関係の中で必要な情報を共有しやすくするための指定です。
オーバーライドは親のメソッドを子クラスらしく作り直すしくみ
オーバーライドも、11章の大きなテーマでした。
オーバーライドとは、スーパークラスと同じメソッド名・同じ引数の形式を持つメソッドを、サブクラス側で定義しなおすことです。
たとえば、DemonSlayer クラスに show() があるとします。
public void show()
{
System.out.println("隊士の名前を表示します。");
System.out.println("階級を表示します。");
}
PillarSlayer クラスでは、担当区域も表示したいので、同じ show() を作り直します。
public void show()
{
System.out.println("柱の名前を表示します。");
System.out.println("階級を表示します。");
System.out.println("担当区域を表示します。");
}
このように、同じ show() でも、PillarSlayer のオブジェクトで呼び出したときは PillarSlayer 側の show() が動きます。
鬼滅の刃風にたとえると、一般隊士には一般隊士の自己紹介があります。
柱には柱としての自己紹介があります。
| クラス | show() の内容 |
|---|---|
| DemonSlayer | 名前と階級を表示 |
| PillarSlayer | 名前、階級、担当区域を表示 |
オーバーライドは、継承が単なる受け継ぎで終わらず、子クラスらしい振る舞いを表現できることを示しています。
スーパークラス型でまとめて扱えることが多態性につながる
11章では、サブクラスのオブジェクトをスーパークラス型の変数で扱えることも学びました。
これは、サブクラスのオブジェクトがスーパークラスの一種でもあるからです。
たとえば、PillarSlayer は DemonSlayer を継承しています。
そのため、次のように書けます。
DemonSlayer slayer1 = new PillarSlayer();
変数の型は DemonSlayer です。
しかし、実際に入っているオブジェクトは PillarSlayer です。
ここで show() を呼び出すと、実体である PillarSlayer 側の show() が動きます。
| 変数の型 | 実体 | show() で動くもの |
|---|---|---|
| DemonSlayer | DemonSlayer | DemonSlayer の show() |
| DemonSlayer | PillarSlayer | PillarSlayer の show() |
これがポリモーフィズム、多態性です。
鬼滅の刃風にたとえると、司令部は全員を「鬼殺隊士」としてまとめて扱えます。
しかし、実際に show() を命じると、一般隊士は一般隊士らしく、柱は柱らしく自己紹介します。
同じ命令でも、実体によって動きが変わる。
これが多態性の大切な感覚です。
オーバーライドとオーバーロードは似ているが別物
11章では、オーバーライドとオーバーロードの違いも整理しました。
名前は似ていますが、意味はかなり違います。
| 用語 | 意味 | 鬼滅の刃風のイメージ |
|---|---|---|
| オーバーロード | 同じメソッド名で、引数の形式が異なるメソッドを複数定義する | 同じ技名で使い方違いを用意する |
| オーバーライド | 親クラスと同じメソッド名・同じ引数の形式のメソッドを子クラスで定義する | 親の技を子が自分流に作り直す |
見分けるときは、引数の形を見ると分かりやすいです。
| 判断ポイント | 結論 |
|---|---|
| 同じ名前で引数が違う | オーバーロード |
| 同じ名前で引数も同じ、継承関係がある | オーバーライド |
鬼滅の刃風にたとえると、useBreathing()、useBreathing(int form)、useBreathing(int form, String target) のように、同じ技名で条件違いを用意するのがオーバーロードです。
一方、DemonSlayer の show() を PillarSlayer で柱用に作り直すのがオーバーライドです。
final はそれ以上変更させないための修飾子
11章では、継承やオーバーライドが便利である一方で、すべてを自由に変えさせればよいわけではないことも学びました。
そこで登場したのが final です。
final は、付ける場所によって意味が変わります。
| final を付ける場所 | 意味 |
|---|---|
| メソッド | オーバーライドできない |
| クラス | 継承できない |
| フィールド | 値を変更できない |
鬼滅の刃風にたとえると、final は「ここは変えてはいけない」という封印のようなものです。
| final の対象 | 鬼滅の刃風のイメージ |
|---|---|
| final メソッド | この技の型は変えるな |
| final クラス | この隊士の型は完成形なので派生させるな |
| final フィールド | この数値は隊の決まりだから変えるな |
継承はクラスを自由に広げるためのしくみです。
しかし、設計では、自由に広げる部分と、固定して守る部分を分けることも大切です。
final は、その境界線をコードに表すための修飾子です。
Java のクラスは最終的に Object クラスにつながる
11章の後半では、Object クラスも学びました。
Javaでは、スーパークラスを指定しないクラスは、自動的に Object クラスのサブクラスになります。
たとえば、次のように書いた場合です。
class DemonSlayer
{
}
extends を書いていなくても、考え方としては次のようになります。
class DemonSlayer extends Object
{
}
つまり、Javaのすべてのクラスは最終的に Object クラスにつながります。
鬼滅の刃風にたとえると、鬼殺隊士、柱、日輪刀、任務書など、いろいろなクラスがあっても、Javaの世界ではすべて「オブジェクト」としての共通土台を持っています。
Object クラスから受け継ぐ代表的なメソッドには、次のものがあります。
| メソッド | 役割 |
|---|---|
| toString() | オブジェクトを表す文字列を返す |
| equals() | オブジェクトが同じかどうかを調べる |
| getClass() | オブジェクトのクラス情報を返す |
Object クラスを理解すると、Javaのクラスがバラバラに存在しているのではなく、共通の親につながっていることが分かります。
toString() はオブジェクトの名乗り方を決める
toString() は、オブジェクトを文字列で表すメソッドです。
オブジェクトを System.out.println() に渡したとき、この toString() の戻り値が表示されます。
System.out.println(slayer1);
このように書いたとき、内部では slayer1.toString() が呼び出され、その戻り値が表示されます。
Object クラス由来の toString() をそのまま使うと、DemonSlayer@1a2b3c のような機械的な表示になりがちです。
そこで、自分のクラスで toString() をオーバーライドすると、分かりやすい文字列を返せるようになります。
| 状態 | 表示例 |
|---|---|
| toString() をオーバーライドしない | DemonSlayer@1a2b3c |
| toString() をオーバーライドする | 名前:水月 階級:水柱 |
鬼滅の刃風にたとえると、toString() は隊士の自己紹介です。
自分の名前や階級を分かりやすく名乗らせるために、toString() を作り直します。
equals() は同じオブジェクトかを調べる基本メソッド
equals() は、2つの変数が同じオブジェクトを指しているかどうかを調べるメソッドです。
Object クラス由来の equals() では、基本的に同じ実体を指している場合に true、別のオブジェクトなら false を返します。
鬼滅の刃風にたとえると、2枚の隊士札があるとします。
その2枚が同じ隊士本人を指しているなら true です。
似ていても別々に作られた隊士を指しているなら false です。
| 比較 | 結果 |
|---|---|
| 同じオブジェクトを指している | true |
| 別々のオブジェクトを指している | false |
また、String クラスでは equals() がオーバーライドされていて、文字列の内容が同じかどうかを見るように作り直されています。
| クラス | equals() の考え方 |
|---|---|
| Object 由来 | 同じ実体かどうか |
| String | 文字列の内容が同じかどうか |
このように、equals() はクラスごとに「同じ」の意味を作り直せるメソッドでもあります。
getClass() はオブジェクトの正体を調べる
getClass() は、オブジェクトが属しているクラスの情報を返すメソッドです。
戻り値は Class クラスのオブジェクトです。
スーパークラス型の配列で複数のオブジェクトをまとめて扱っているときでも、getClass() を使えば、そのオブジェクトが実際にはどのクラスなのかを確認できます。
たとえば、次のような配列を考えます。
DemonSlayer[] slayers = new DemonSlayer[2];
slayers[0] = new DemonSlayer();
slayers[1] = new PillarSlayer();
配列の型は DemonSlayer[] です。
しかし、中に入っている実体は異なります。
| 配列要素 | 実体 | getClass() の結果 |
|---|---|---|
| slayers[0] | DemonSlayer | class DemonSlayer |
| slayers[1] | PillarSlayer | class PillarSlayer |
鬼滅の刃風にたとえると、名簿では全員が鬼殺隊士として並んでいても、実際には一般隊士や柱が混ざっています。
getClass() を使うと、その正体を確認できます。
図:11章全体の継承の流れ
↓クリックすると拡大表示されます。

この図が示していること
この図では、11章で学んだ継承の全体像を表しています。
一番上には Object クラスがあります。
その下に DemonSlayer、PillarSlayer、WaterPillarSlayer が続きます。
この階層から、Javaのクラスは最終的に Object クラスにつながり、そこから共通の基本機能を受け継ぐことが分かります。
また、DemonSlayer には共通部分を置き、PillarSlayer では担当区域やオーバーライドした show() を追加しています。
右側の protected は、親子関係の中で子クラスにも使わせたいメンバを表します。
左側の final は、変更させたくない部分を固定するための仕組みを表します。
図:ポリモーフィズムと Object の基本メソッド
↓クリックすると拡大表示されます。

この図が示していること
この図では、11章後半で学んだポリモーフィズムと Object クラスの基本メソッドを整理しています。
左側では、DemonSlayer[] 配列に DemonSlayer オブジェクトと PillarSlayer オブジェクトが一緒に入っています。
同じ slayers[i].show() という呼び出しでも、実体が DemonSlayer なら DemonSlayer の show()、実体が PillarSlayer なら PillarSlayer の show() が動きます。
右側では、Object クラス由来の基本メソッドをまとめています。
| メソッド | 役割 |
|---|---|
| toString() | オブジェクトの名乗り方を決める |
| equals() | 同じ実体かどうかを確認する |
| getClass() | 実体のクラス情報を確認する |
この図から分かることは、スーパークラス型でまとめて扱っても、実体ごとの個性は消えないということです。
さらに、どのクラスも Object クラス由来の基本機能を持っていることも分かります。
11章でいちばん大事な感覚
11章で学んだことをひとつの感覚にまとめるなら、
親クラスを土台にして、新しいクラスを作り、その関係の中で役割を分けていく考え方
です。
鬼滅の刃風にたとえると、共通の鬼殺隊士の型があり、そこから柱や水柱のような個性ある型が生まれます。
しかし、それぞれが完全にバラバラなのではありません。
共通部分は親にあります。
個性は子にあります。
同じ命令でも、実体によって動きが変わります。
そして、すべてのクラスは Object という共通の土台につながっています。
| 11章の考え方 | 内容 |
|---|---|
| 共通部分は親にまとめる | DemonSlayer に name、rank、show() などを置く |
| 個性は子に追加する | PillarSlayer に area などを追加する |
| 必要なら作り直す | show() をオーバーライドする |
| まとめて扱う | DemonSlayer 型で PillarSlayer を扱う |
| 実体ごとに動きを変える | ポリモーフィズム |
| 守る部分は固定する | final を使う |
| すべてのクラスは Object につながる | toString()、equals()、getClass() を受け継ぐ |
この感覚がつかめると、継承は単なる文法ではなく、クラス設計そのものを考えるための強力な考え方だと分かります。
