Java入門|12章のまとめ

抽象クラスで土台を整え、インターフェイスで約束を結ぶ。
12章は、オブジェクト指向を「大きな設計」へ育てるための力を学ぶ章です。

12章では、Javaのオブジェクト指向をさらに一歩進めるために、抽象クラスとインターフェイスを学びました。
11章で継承の基本を学んだことで、親クラスから子クラスへ機能を受け継ぐ考え方は見えてきましたが、12章ではそこからさらに、共通の土台だけを用意する方法 や、クラスをまたいで共通の約束を持たせる方法 が出てきました。

ドラゴンボールでたとえると、11章までで学んだのは、サイヤ人という戦士の型を土台にして、そこから新しい戦士クラスを広げていく考え方でした。
それに対して12章で学んだのは、もっと大きな視点です。

  • 戦士なら共通して持つべき基本の土台は何か
  • どの戦士も必ずできるべきことは何か
  • 気を使える者、飛べる者、表示できる者といった能力の約束をどう整理するか
  • 多くのキャラクターを、どうやって同じルールでまとめて扱うか

こうしたことを考えるために、抽象クラスとインターフェイスが登場しました。

抽象クラスは、まだ完成していないけれど共通部分を持った「土台」です。
インターフェイスは、クラスの種類に関係なく「この約束を守る」と決めるための仕組みです。

この2つを使えるようになると、コードはただ動くだけではなく、整理され、増やしやすく、読みやすい形 になっていきます。
12章は、Javaのオブジェクト指向を、単なる継承の学習から、設計の学習へ進める章だったと言えます。

抽象クラスは「未完成の土台」を作るための仕組み

12章で最初に学んだ大きなテーマは、抽象クラスでした。

抽象クラスは、普通のクラスのようにフィールドやメソッドを持てます。
ただし、そのままでは完成していないクラスです。
そのため、抽象クラスそのものからオブジェクトを作成することはできません。

ドラゴンボールでいえば、抽象クラスは「戦士」という共通の設計図のようなものです。

たとえば戦士なら、

  • 名前を持つ
  • 速度を持つ
  • 基本の行動を持つ

といった共通点があります。
けれども、自己紹介のしかたや戦闘スタイルは、悟空、ベジータ、ピッコロでまったく同じではありません。

そこで抽象クラスでは、

  • 共通の状態や共通の処理は書いておく
  • でも具体的な中身は子クラスで完成させる

という形を取ります。

この考え方によって、共通部分を親クラスにきれいに集めつつ、個性は子クラスに任せることができます。
これが、抽象クラスのいちばん大切な役割です。

抽象メソッドは「必ず持つべき処理」を宣言する

抽象クラスの中では、抽象メソッドを宣言できます。
抽象メソッドとは、処理内容を書かずに、名前だけを決めておくメソッドです。

これは、ドラゴンボールでいうと
「戦士なら、この行動は必ず持つべきだ」
という約束だけを先に決めておくようなものです。

たとえば、

  • 戦士なら情報を表示できる
  • 戦士なら移動方法を表せる

というルールは共通でも、その中身は戦士ごとに違います。

そこで親クラスでは、メソッド名だけを用意しておき、子クラスでその内容を完成させます。
この仕組みによって、親クラスは共通ルールを示し、子クラスはそれを自分らしく実装できるようになります。

抽象クラスのオブジェクトは作成できない理由

12章では、抽象クラスのオブジェクトを作成できないことも学びました。

これはとても自然なことです。
なぜなら、抽象クラスはまだ完成していないからです。

ドラゴンボールでいえば、「戦士」という言葉だけでは、まだ悟空でもベジータでもピッコロでもありません。
ただの共通概念だけでは、具体的な存在として扱えないのです。

だから抽象クラスは、

  • 共通の土台として使う
  • 子クラスを作るために使う
  • そのまま実体化はしない

という立場になります。

この感覚がつかめると、抽象クラスは「半端なクラス」ではなく、設計を整理するための意図的な未完成さ を持つクラスだと見えてきます。

インターフェイスは「何ができるか」の約束を表す

12章でもうひとつ大きかったテーマが、インターフェイスです。

インターフェイスは、クラスと少し似ていますが、役割はかなり違います。
抽象クラスが共通の土台を表すのに対して、インターフェイスは
何ができるか
という約束を表します。

ドラゴンボールで考えると、

  • 気を使える
  • 飛べる
  • 情報を表示できる

といった能力は、種族や戦士の型とは別のルールです。

サイヤ人だけでなく、ピッコロも飛べますし、ほかの戦士も気を使えるかもしれません。
こういうとき、クラスだけで整理しようとすると苦しくなります。

そこでインターフェイスを使うと、

  • この型に属するものは、必ずこのメソッドを持つ
  • でも中身は各クラスが決めてよい

という形で、能力の約束を表せます。

この考え方は、オブジェクト指向をとても自然なものにしてくれます。
「何者か」だけでなく、「何ができるか」でもクラスを整理できるようになるからです。

インターフェイスのフィールドは定数になる

12章では、インターフェイスのフィールドは定数になることも学びました。

これは、インターフェイスが本来「共通の約束」を表すものであって、変化する状態を持たせる場所ではないからです。

ドラゴンボールでたとえるなら、インターフェイスに書くフィールドは、個々の戦士の今の状態ではなく、
「この能力ルールに共通する決まり」
のようなものです。

つまりインターフェイスは、

  • 状態を管理する場所ではない
  • 共通ルールや固定値を示す場所

として使うのが基本です。

この特徴があるからこそ、インターフェイスは能力や約束だけをすっきり表す役割に集中できます。

インターフェイスのメソッドは抽象メソッドになる

インターフェイスのメソッドは、処理内容を定義しない抽象メソッドになります。
これも、インターフェイスが「約束」を表す仕組みだからです。

ドラゴンボールで言えば、インターフェイスは

  • 気を使える者なら、この技を使う仕組みを持つ
  • 表示できる者なら、この表示メソッドを持つ

といったことを決めるだけで、実際の技の出し方までは書かないのです。

その中身は、悟空なら悟空、ベジータならベジータというように、実装するクラスが決めます。

ここがとても大切です。
インターフェイスは、メソッド名を並べるだけのものではありません。
共通の行動ルールを、クラスに守らせるための仕組み なのです。

インターフェイスを実装すると、多くのクラスをまとめて扱える

インターフェイスを使う大きな利点は、複数のクラスを同じ型としてまとめて扱えることです。

たとえばドラゴンボール風に、

  • Saiyan
  • NamekianWarrior
  • EarthWarrior

というクラスがあったとします。

これらが同じインターフェイスを実装していれば、使う側のコードは細かなクラス名を意識せずに、同じメソッド名でまとめて扱えます。

これは多態性と深くつながっています。
同じ命令で呼び出しても、実際にはそれぞれのクラスに合った処理が動くからです。

つまりインターフェイスは、
違うクラスを同じルールで扱うための入口
だと言えます。

スーパーインターフェイスを拡張して、サブインターフェイスを作れる

12章では、インターフェイスどうしにも親子関係を作れることを学びました。

インターフェイスは extends を使って拡張できます。
このとき、

  • 拡張される側がスーパーインターフェイス
  • 拡張する側がサブインターフェイス

です。

ドラゴンボールでたとえると、これは能力のルールを段階的に強くしていく感覚です。

たとえば、

  • 基本の移動能力を持つ
  • その上で戦士としての飛行能力も持つ
  • さらに表示用の能力も持つ

というように、能力の約束を1段ずつ積み上げていけます。

この仕組みを使うと、インターフェイスをいきなり大きくせずに、

  • 基本ルール
  • 発展ルール
  • 上位ルール

という形で、能力の約束を整理できます。

これが、サブインターフェイスを使う大きな意味です。

抽象クラスとインターフェイスを使うと、多態性でわかりやすいコードが書ける

12章全体を通して見えてきた大事なことは、抽象クラスとインターフェイスを使うと、多態性によってとてもわかりやすいコードが書ける、という点です。

ドラゴンボールで考えると、

  • 戦士としての共通の土台は抽象クラスにまとめる
  • 能力の約束はインターフェイスで表す
  • 実際のキャラクターは具体クラスで作る

という形にできます。

すると、コードを書くときには

  • 個別のクラスを細かく意識しなくてもよい
  • 共通の型でまとめて扱える
  • 同じメソッド呼び出しで、それぞれに合った処理が動く

ようになります。

この「共通のルールでまとめつつ、中身はクラスごとに違ってよい」という考え方が、多態性の気持ちよさです。
12章では、そのための道具として、抽象クラスとインターフェイスを学んだと言えます。

大規模なプログラムでは、抽象クラスとインターフェイスが特に重要になる

Javaでは多くのクラスやインターフェイスを組み合わせながら、大きなプログラムを作っていきます。

クラスが少ないうちは、個別に処理を書いても何とかなるかもしれません。
でも規模が大きくなると、

  • 共通の土台をどこに置くか
  • 共通の能力の約束をどこで表すか
  • 新しいクラスをどう追加するか
  • 差し替えに強い設計をどう作るか

を考えないと、全体がすぐに複雑になります。

そこで、

  • 抽象クラスで共通の土台を整理する
  • インターフェイスで能力の約束を整理する
  • 多態性でクラスをまとめて扱う

という設計が、とても大切になります。

つまり12章は、Javaのオブジェクト指向を「大きく育てる」ための章だったと言えます。

12章で学んだ内容を表で整理

ここまでの内容を整理すると、12章では次のようなことを学んだことになります。

学んだこと意味
抽象クラスを宣言できる未完成の共通土台を作れる
抽象クラスは抽象メソッドを持てる子クラスに必ず実装させたい処理を宣言できる
抽象クラスのオブジェクトは作れないそのままでは未完成だから
インターフェイスを宣言して実装できる能力や約束をクラスに持たせられる
インターフェイスのフィールドは定数になる固定された共通ルールを表す
インターフェイスのメソッドは抽象メソッドになる処理内容は実装クラスが決める
サブインターフェイスを宣言できる約束を段階的に拡張できる

この表を見ると、12章は単に新しいキーワードを覚える章ではなく、共通化・整理・拡張のための考え方を学ぶ章 だったことがよくわかります。

図で12章全体の流れを整理する

12章は内容が広かったので、全体を図にするとかなり整理しやすくなります。

上部中央の Warrior抽象クラス は、戦士としての共通の土台を表しています。
ここには名前や速度、共通メソッド、そして未完成の抽象メソッドが置かれています。

左上や右上のインターフェイスは、能力の約束を表しています。
さらに iFlyingWarrior のようなサブインターフェイスが、親の約束を受け継いで発展した能力ルールを表しています。

中央の Saiyanクラス は、抽象クラスを継承しながら、必要なインターフェイスを実装しています。
下部の NamekianWarriorクラス や EarthWarriorクラス も、同じように共通の土台と能力ルールを組み合わせて表現されています。

この図から、12章で学んだことが、ばらばらの知識ではなく、

  • 共通の土台を作る
  • 能力の約束を整理する
  • クラスをまとめて扱う
  • 大きな設計へつなげる

というひとつの流れになっていることが見えてきます。

12章でいちばん大事な感覚

最後に、12章をひとつの感覚にまとめるとこうなります。

12章で学んだのは、
共通の土台と共通の約束を使って、多くのクラスを整理しながら扱う考え方
です。

ドラゴンボールで言えば、

  • 抽象クラスで戦士としての基本を作る
  • インターフェイスで飛べる、気を使えるといった能力の約束を作る
  • 具体クラスで悟空やベジータやピッコロの個性を表現する
  • それでも全体としては、同じルールでまとめて扱えるようにする

ということです。

この感覚がつかめると、Javaのオブジェクト指向は、単なる継承の仕組みではなく、大きなプログラムを整理するための設計技法 だと見えてきます。
12章は、そのための土台をしっかり作る章でした。