Java入門|インターフェイスの拡張と継承のしくみ

能力の約束も、親から子へ進化していく。
インターフェイスの拡張を理解すると、ドラゴンボールの力の系譜のように、役割を段階的に整理できるようになる。

インターフェイスは、クラスのように「何者か」を表すものではなく、「何ができるか」という約束を表す仕組みでした。
そして Java では、このインターフェイスどうしにも親子関係を作ることができます。これが、インターフェイスの拡張です。

ドラゴンボールでたとえるなら、まず「気を使える戦士」という基本の約束があり、その上に「気を使って飛べる戦士」という、もう少し具体的な約束を重ねるようなイメージです。
つまり、最初にある能力ルールを土台にして、そのルールを受け継ぎながら、さらに新しい能力の約束を加えていけるわけです。

この考え方を使うと、

  • 基本の能力をスーパーインターフェイスにまとめる
  • そこから発展した能力をサブインターフェイスとして作る
  • 最後にクラスがそれらを実装する

という、きれいな階層が作れます。

今回は、この「インターフェイスの拡張と継承のしくみ」を、ドラゴンボールの能力ルールに置きかえながら、やわらかく整理していきます。

インターフェイスも拡張できる

Java では、クラスだけでなくインターフェイスも拡張できます。
このとき、拡張される側をスーパーインターフェイス、拡張する側をサブインターフェイスと呼びます。

形は次のようになります。

interface サブインターフェイス名 extends スーパーインターフェイス名1, スーパーインターフェイス名2, ...
{
    ...
}

ここで大事なのは、サブインターフェイスは、スーパーインターフェイスの約束をそのまま受け継ぐということです。
つまり、新しい約束をゼロから作るのではなく、親の約束を含んだ発展版の約束を作るわけです。

ドラゴンボールで考えるインターフェイスの拡張

ここはドラゴンボールに置きかえると、とてもイメージしやすくなります。

たとえば、まず基本の能力ルールとして

  • iKiMovable
    気を使って動ける者の約束

があるとします。

このインターフェイスには、たとえば move() のようなメソッドがあると考えます。
これは「気を使って移動できる者なら、移動の処理を必ず持つべきだ」という約束です。

次に、その上位版として

  • iFlyingWarrior
    気を使って動けるうえに、戦士としての飛行能力も表現できる者の約束

を作るとします。

このとき、

interface iFlyingWarrior extends iKiMovable
{
    ...
}

のように書けば、iFlyingWarrior は iKiMovable の約束を受け継ぎながら、自分の新しい約束を加えたサブインターフェイスになります。

つまりドラゴンボール風に言えば、

  • iKiMovable は「気を使って動ける」という基本能力
  • iFlyingWarrior は「気を使って動ける」ことを前提に、「戦士として飛行能力も持つ」という発展能力

という関係です。

スーパーインターフェイスとサブインターフェイスの関係

この親子関係を整理すると、次のようになります。

役割意味
スーパーインターフェイス基本となる能力の約束
サブインターフェイス親の約束を受け継いだ上で、さらに発展した能力の約束

ドラゴンボールでいえば、スーパーインターフェイスは「戦士の基本能力のルール」、サブインターフェイスは「その基本能力を土台にした上位ルール」です。

たとえば、

  • 気を使って移動できる
  • さらに飛行戦闘のルールも守る
  • さらに表示用の情報も見せられる

というふうに、能力の約束を段階的に積み上げていけます。

この考え方があると、能力をいきなり全部ひとつのインターフェイスに詰め込まなくてすむので、役割をきれいに整理しやすくなります。

インターフェイスの拡張には extends を使う

クラスの継承にも extends を使いましたが、インターフェイスの拡張でも同じく extends を使います。

ただし、意味は少し違います。

書き方意味
クラスの extendsクラスが親クラスを継承する
インターフェイスの extendsインターフェイスが親インターフェイスの約束を受け継ぐ

つまり、クラスでの extends は「土台を受け継ぐ」感じで、インターフェイスでの extends は「能力の約束を受け継ぐ」感じです。

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

  • クラスの継承は「サイヤ人」という型を受け継ぐ
  • インターフェイスの拡張は「気を使える」という能力ルールを受け継ぐ

という違いになります。

クラスがサブインターフェイスを実装するとどうなるか

ここがとても大切です。

サブインターフェイスをクラスが実装した場合、そのクラスはサブインターフェイス自身が持つメソッドだけでなく、スーパーインターフェイスから受け継いだメソッドも定義しなければなりません。

つまり、親インターフェイスの約束も、子インターフェイスの約束も、全部まとめて引き受けることになります。

ドラゴンボール風にたとえるなら、もし

  • iKiMovable が move() を持つ
  • iFlyingWarrior が show() を持つ
  • iFlyingWarrior extends iKiMovable

という関係なら、iFlyingWarrior を実装するクラスは、

  • move()
  • show()

の両方を定義しなければなりません。

つまり「飛べる戦士」と名乗るなら、ただ飛べるだけではだめで、前提となる「気を使って動ける」という基本能力も持っていなければならない、ということです。

implements はクラスが約束を引き受けるためのもの

インターフェイスどうしの関係では extends を使いますが、クラスがインターフェイスを実装するときには implements を使います。

この違いはしっかり分けておくとわかりやすいです。

キーワード使う場面意味
extendsインターフェイス → インターフェイス約束を受け継いで新しい約束を作る
implementsクラス → インターフェイスクラスがその約束を実際に守る

ドラゴンボールでたとえるなら、

  • extends は 能力ルールどうしの親子関係
  • implements は 実際の戦士クラスがその能力ルールを受け入れること

です。

この区別がつくと、インターフェイスの階層がかなり整理しやすくなります。

インターフェイスの拡張が便利な理由

インターフェイスを拡張できると、能力や約束を段階的に整理できます。
これがとても大きな利点です。

たとえば、何でも最初からひとつのインターフェイスに詰め込んでしまうと、「どこまでが基本能力で、どこからが発展能力なのか」が見えにくくなります。

でも、インターフェイスを親子関係で分けると、

  • 基本能力の約束
  • 発展能力の約束
  • さらに上位の能力の約束

というふうに整理できます。

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

  • まず「気を使える」
  • 次に「気を使って移動できる」
  • さらに「気を使って移動し、戦士として情報を表示できる」

というふうに、能力ルールを進化させる感覚です。

この整理ができると、設計の見通しがとてもよくなります。

クラスの継承との違い

ここで、クラスの継承とインターフェイスの拡張の違いを整理しておくと理解が深まります。

比較項目クラスの継承インターフェイスの拡張
表すもの何者か、共通の土台何ができるか、能力の約束
親の数1つだけ複数可
主な役割共通の状態や処理を受け継ぐ共通のルールを受け継ぐ

つまり、

  • クラスの継承は「型の系譜」
  • インターフェイスの拡張は「能力ルールの系譜」

と考えると、とてもわかりやすいです。

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

  • クラスの継承は「サイヤ人」から「エリートサイヤ人」へ
  • インターフェイスの拡張は「気を使える」から「気を使って飛べる」へ

という違いです。

図でインターフェイスの拡張を整理する

インターフェイスの拡張は、親インターフェイス、子インターフェイス、実装クラスの流れを図で見るととても理解しやすくなります。

左上の iKiMovableインターフェイス は、「気を使って動ける者」の基本の約束を表しています。
右上の iFlyingWarriorインターフェイス は、それを extends で受け継いだサブインターフェイスです。

そのため iFlyingWarrior は、自分が持つ show() の約束だけでなく、iKiMovable の move() も含んでいます。

下の Saiyanクラス は iFlyingWarrior を implements しているので、show() だけでなく、move() も定義しなければなりません。
この図から、インターフェイスの親子関係が、そのまま実装クラスに受け継がれていくことが見えてきます。

ドラゴンボールで感覚的に整理する

最後に、ドラゴンボールの感覚でまとめてみましょう。

インターフェイスの拡張は、能力の約束を親から子へ進化させていく仕組みです。

  • iKiMovable は「気を使って動ける」
  • iFlyingWarrior は「気を使って動ける」うえに「戦士として表示もできる」

というように、基本能力を含んだ上位ルールを作れます。

そして、その上位ルールを実装するクラスは、親の約束も子の約束も全部守らなければなりません。

つまり、インターフェイスの拡張とは
戦士の能力ルールを、ドラゴンボールの修行や進化のように段階的に積み上げていく仕組み
だと考えると、とてもわかりやすいです。

この感覚がつかめると、インターフェイスは単なるメソッド名の集まりではなく、能力や約束を階層的に整理するための強力な道具だと見えてきます。