
Java超|インターフェイスの複数実装
親クラスは1つだけ。でも、戦士が背負う奥義の約束は、いくつでも組み合わせられる。
Javaでは、1つのクラスが継承できる親クラスは1つだけです。
つまり、クラスの親を複数持つような多重継承はできません。
しかし、実際のオブジェクト指向では、1つのクラスに複数の能力や役割を持たせたい場面があります。
ドラゴンボールの世界観で考えると、1人の戦士は1つの特徴だけで成り立っているわけではありません。
たとえば、あるオリジナル戦士が次のような力を持っているとします。
| 性質 | ドラゴンボール風のイメージ |
|---|---|
| 戦士である | 戦闘できる |
| 気を解放できる | releaseKi() で気を放てる |
| 戦闘装備を持つ | showArmor() で装備情報を示せる |
| 仲間を支援できる | 治療や補助の力を使える |
| 空中移動できる | 舞空術のように飛べる |
このように、1つのクラスが複数の能力を持つことは自然です。
Javaでは、クラスの親は1つだけに制限されています。
その代わりに、インターフェイスは複数実装できます。
この記事では、インターフェイスの複数実装を、ドラゴンボールの世界観で、1人の戦士が複数の奥義契約を同時に引き受けるしくみとして解説します。
Javaではクラスの多重継承はできない
まず、出発点として大切なのは、Javaでは1つのクラスが2つ以上の親クラスを同時に継承できないということです。
たとえば、次のような2つのクラスがあるとします。
class Warrior
{
}
class ArmorUser
{
}Warrior は戦士としての基本クラスです。
ArmorUser は戦闘装備を使う者としての基本クラスです。
この2つを同時に親クラスとして持つように、次のような書き方はできません。
class SuperSaiyanGuardian extends Warrior, ArmorUser
{
}Javaのクラス継承では、extends のあとに指定できる親クラスは1つだけです。
| 書き方 | Javaで可能か | 理由 |
|---|---|---|
| class SuperSaiyanGuardian extends Warrior | 可能 | 親クラスが1つだけ |
| class SuperSaiyanGuardian extends Warrior, ArmorUser | 不可能 | 親クラスを複数指定している |
ドラゴンボール風にたとえると、1人の戦士クラスが「サイヤ人戦士の基本クラス」と「装備使いの基本クラス」を、同時に親として持つことはできないということです。
Javaでは、クラスの継承関係は1本の系譜として整理します。
そのため、クラスそのものの多重継承は禁止されています。
なぜクラスの多重継承はできないのか
クラスの多重継承ができると、一見とても便利そうに見えます。
しかし、複数の親クラスを同時に持つと、設計が複雑になりやすいです。
たとえば、2つの親クラスが同じ名前のメソッドを持っていたらどうなるでしょうか。
class Warrior
{
void show()
{
System.out.println("戦士の情報を表示します。");
}
}
class ArmorUser
{
void show()
{
System.out.println("戦闘装備の情報を表示します。");
}
}もし、1つのクラスがこの2つを同時に継承できた場合、show() を呼び出したときに、どちらの show() を使うのか分かりにくくなります。
| 起こりやすい問題 | 内容 |
|---|---|
| 同名メソッドの衝突 | どちらの親のメソッドを使うか迷う |
| 同名フィールドの衝突 | どちらの値を指すのか分かりにくい |
| 初期化順序が複雑 | どの親クラスを先に初期化するのか迷う |
| 設計が読みにくい | クラスの責任範囲があいまいになる |
ドラゴンボール風にたとえると、1人の戦士が2つの流派の親クラスを同時に受け継ぎ、両方に同じ名前の奥義がある状態です。
たとえば、亀仙流にも show() があり、神流にも show() があるとします。
そのとき、戦士が show() を使ったら、亀仙流の情報表示なのか、神流の情報表示なのか分かりにくくなります。
Javaは、このような混乱を避けるために、クラスの親は1つだけというルールにしています。
図:Javaではクラスの親は1つだけ

この図が示していること
この図では、Javaのクラス継承では親クラスを1つだけ指定できることを表しています。
左側は、SuperSaiyanGuardian が Warrior だけを継承しているので正しい形です。
右側は、SuperSaiyanGuardian が Warrior と ArmorUser の2つを同時に継承しようとしているため、Javaではできない形です。
| しくみ | Javaでの扱い |
|---|---|
| 1つの親クラスを継承 | できる |
| 複数の親クラスを継承 | できない |
この図から分かることは、Javaではクラスの系譜を1本に保つことで、同名メソッドの衝突や設計の混乱を避けているということです。
それでも複数の能力を持たせたい場面はある
クラスの多重継承ができないとはいえ、1つのクラスに複数の能力を持たせたい場面はたくさんあります。
ドラゴンボール風に考えると、ある戦士は次のような複数の力を持つかもしれません。
| 持たせたい性質 | 例 |
|---|---|
| 気を解放できる | 金色の気を放つ |
| 装備情報を示せる | 戦闘ジャケットやスカウターを表示する |
| 空を飛べる | 舞空術で移動する |
| 仲間を支援できる | 治療や補助を行う |
もしクラス継承だけに頼ると、これらを柔軟に組み合わせるのが難しくなります。
そこで Java では、クラスの多重継承は許さない代わりに、インターフェイスの複数実装を使います。
Javaは、次のように役割を分けています。
| しくみ | 役割 |
|---|---|
| クラスの継承 | 親クラスは1つだけにして、構造を整理する |
| インターフェイスの実装 | 複数の能力や約束を持たせる |
この分け方によって、Javaは分かりやすさと柔軟さを両立しています。
ドラゴンボール風に言えば、
戦士としての血筋や土台は1本にする。けれど、身につける奥義や契約は複数持てる
というイメージです。
インターフェイスの複数実装とは何か
Javaでは、1つのクラスが2つ以上のインターフェイスを実装できます。
このときは、implements のあとにインターフェイス名をカンマで並べます。
基本形は次のとおりです。
class クラス名 implements インターフェイス名1, インターフェイス名2
{
}ドラゴンボール風に、次の2つのインターフェイスを考えます。
| インターフェイス | 役割 |
|---|---|
| iKiUser | 気を解放する約束 |
| iBattleArmor | 戦闘装備の情報を示す約束 |
この2つを、1つの SuperSaiyanGuardian クラスが実装できます。
class SuperSaiyanGuardian implements iKiUser, iBattleArmor
{
}これは、SuperSaiyanGuardian クラスが次の2つの約束を同時に引き受けるという意味です。
| 引き受ける約束 | 必要なメソッド |
|---|---|
| iKiUser の約束 | releaseKi() |
| iBattleArmor の約束 | showArmor() |
ドラゴンボール風にたとえると、SuperSaiyanGuardian は、
気を解放できる戦士でもあり、戦闘装備の情報も示せる戦士でもある
ということです。
なぜインターフェイスの複数実装が多重継承の考え方につながるのか
ここで大切なのは、インターフェイスの複数実装は、クラスそのものを複数継承しているわけではないという点です。
複数の親クラスからフィールドや具体的な処理を受け継ぐわけではありません。
受け取るのは、主にメソッド名の約束です。
たとえば、次のような2つのインターフェイスがあるとします。
interface iKiUser
{
void releaseKi();
}
interface iBattleArmor
{
void showArmor();
}この2つを実装するクラスは、releaseKi() と showArmor() の両方を定義しなければなりません。
class SuperSaiyanGuardian implements iKiUser, iBattleArmor
{
public void releaseKi()
{
}
public void showArmor()
{
}
}つまり、複数のインターフェイスが定めたメソッドのルールを、1つのクラスがまとめて引き受けているわけです。
| 多重継承の種類 | Javaでの扱い |
|---|---|
| 複数のクラスを同時に継承する | できない |
| 複数のインターフェイスを同時に実装する | できる |
| 複数の約束を1つのクラスに持たせる | できる |
ドラゴンボール風にたとえると、1人の戦士が複数の親を持つのではありません。
そうではなく、
気を解放する契約
戦闘装備を示す契約
のように、複数の奥義契約を同時に守るというイメージです。
だから、インターフェイスの複数実装は、Javaで多重継承の考え方の一部を安全に実現する方法だと考えられます。
ファイル名:Sample4.java
interface iKiUser
{
void releaseKi();
}
interface iBattleArmor
{
void showArmor();
}
class SuperSaiyanGuardian implements iKiUser, iBattleArmor
{
private String name;
private int battlePower;
private String armorName;
public SuperSaiyanGuardian(String n, int bp, String an)
{
name = n;
battlePower = bp;
armorName = an;
System.out.println(name + " 戦闘力" + battlePower + "のスーパーサイヤ人守護戦士を作成しました。");
}
public void releaseKi()
{
System.out.println(name + "が金色の気を解放しました。");
System.out.println("戦闘力は" + battlePower + "です。");
}
public void showArmor()
{
System.out.println(name + "の戦闘装備は" + armorName + "です。");
}
}
class Sample4
{
public static void main(String[] args)
{
SuperSaiyanGuardian warrior1 = new SuperSaiyanGuardian("蒼月", 18000, "青紋バトルジャケット");
warrior1.releaseKi();
warrior1.showArmor();
}
}実行結果
蒼月 戦闘力18000のスーパーサイヤ人守護戦士を作成しました。
蒼月が金色の気を解放しました。
戦闘力は18000です。
蒼月の戦闘装備は青紋バトルジャケットです。SuperSaiyanGuardian が2つのインターフェイスを実装している
このプログラムでは、SuperSaiyanGuardian クラスが2つのインターフェイスを実装しています。
class SuperSaiyanGuardian implements iKiUser, iBattleArmorここで実装しているのは、次の2つです。
| 実装しているもの | 意味 |
|---|---|
| iKiUser | 気を解放する約束を守る |
| iBattleArmor | 戦闘装備の情報を示す約束を守る |
つまり SuperSaiyanGuardian は、iKiUser の約束も、iBattleArmor の約束も引き受けています。
そのため、SuperSaiyanGuardian クラスでは、両方のインターフェイスが要求するメソッドを定義する必要があります。
| インターフェイス | 要求するメソッド | SuperSaiyanGuardian で定義する必要 |
|---|---|---|
| iKiUser | releaseKi() | 必要 |
| iBattleArmor | showArmor() | 必要 |
このように、インターフェイスを複数実装するということは、複数の約束を同時に引き受けることです。
ドラゴンボール風にたとえると、SuperSaiyanGuardian は、
気を解放する奥義契約
戦闘装備を示す装備契約
の両方を持つ戦士です。
releaseKi() と showArmor() は何を表しているのか
この例では、2つのインターフェイスが別々の役割を持っています。
interface iKiUser
{
void releaseKi();
}iKiUser は、気を解放する約束です。
interface iBattleArmor
{
void showArmor();
}iBattleArmor は、戦闘装備の情報を示す約束です。
SuperSaiyanGuardian クラスでは、この2つを次のように実装しています。
public void releaseKi()
{
System.out.println(name + "が金色の気を解放しました。");
System.out.println("戦闘力は" + battlePower + "です。");
}releaseKi() では、戦士が金色の気を解放し、戦闘力を表示しています。
public void showArmor()
{
System.out.println(name + "の戦闘装備は" + armorName + "です。");
}showArmor() では、戦闘装備として青紋バトルジャケットを表示しています。
整理すると、次のようになります。
| メソッド | 役割 | 表示内容 |
|---|---|---|
| releaseKi() | 気の解放 | 名前、気の解放、戦闘力 |
| showArmor() | 戦闘装備の情報表示 | 装備名 |
同じ SuperSaiyanGuardian オブジェクトが、2つの異なる役割を持っていることが分かります。
図:2つのインターフェイスを1つのクラスが実装する

この図が示していること
この図では、iKiUser と iBattleArmor という2つのインターフェイスから、SuperSaiyanGuardian クラスへ約束が集まる様子を表しています。
iKiUser は releaseKi() という約束を持っています。
iBattleArmor は showArmor() という約束を持っています。
SuperSaiyanGuardian は、その両方を implements で実装しています。
| インターフェイス | 約束 | SuperSaiyanGuardian の責任 |
|---|---|---|
| iKiUser | releaseKi() を持つ | releaseKi() を定義する |
| iBattleArmor | showArmor() を持つ | showArmor() を定義する |
この図から分かることは、Javaではクラスの多重継承はできなくても、インターフェイスを使えば複数のメソッドの約束を1つのクラスに集められるということです。
なぜクラスの多重継承より扱いやすいのか
クラスの多重継承では、複数の親クラスから具体的なフィールドやメソッドを受け継ぐことになります。
そのため、同じ名前のメンバがあったときに衝突しやすくなります。
一方、インターフェイスは、主に「こういうメソッドを持つこと」という約束を表します。
そのため、役割を分けやすく、クラス構造も複雑になりにくいです。
| しくみ | 役割 |
|---|---|
| クラスの継承 | 共通の土台を受け継ぐ |
| インターフェイス | 能力や約束を追加する |
ドラゴンボール風にたとえると、クラスは「SuperSaiyanGuardian という存在そのもの」を表します。
一方、インターフェイスは、次のような能力ルールを表します。
| インターフェイス | 能力ルール |
|---|---|
| iKiUser | 気を解放できる |
| iBattleArmor | 戦闘装備の情報を示せる |
つまり、クラスで「何者か」を表し、インターフェイスで「何ができるか」を追加しているわけです。
この整理があるので、Javaではクラスの多重継承を使わなくても、複数の能力を自然に表現できます。
インターフェイスの複数実装が便利な場面
インターフェイスの複数実装は、1つのクラスに複数の役割を持たせたいときに便利です。
ドラゴンボール風に考えると、次のような使い方ができます。
| インターフェイス | 役割 |
|---|---|
| iKiUser | 気を解放できる |
| iBattleArmor | 戦闘装備の情報を示せる |
| iFlyable | 空中移動できる |
| iHealer | 仲間を回復できる |
たとえば、将来的に SuperSaiyanGuardian に飛行能力の約束も追加したい場合は、次のようにできます。
class SuperSaiyanGuardian implements iKiUser, iBattleArmor, iFlyable
{
}このように、親クラスを増やさなくても、必要な能力の約束を増やせます。
| 目的 | インターフェイスでの表現 |
|---|---|
| 気を解放できることを保証したい | iKiUser |
| 戦闘装備を示せることを保証したい | iBattleArmor |
| 飛行できることを保証したい | iFlyable |
| 回復できることを保証したい | iHealer |
これにより、クラスは1つの基本構造を保ちながら、能力や役割の面では柔軟に広げられます。
抽象クラスとの違いも意識しておきたい
インターフェイスの複数実装を理解するには、抽象クラスとの違いも押さえておくと分かりやすいです。
| 比較項目 | 抽象クラス | インターフェイス |
|---|---|---|
| 役割 | 共通の土台 | 共通の約束 |
| 通常フィールド | 持てる | 原則として持てない |
| 通常メソッド | 持てる | 原則として処理を書かない |
| コンストラクタ | 持てる | 持てない |
| 継承・実装 | extends で1つだけ | implements で複数可 |
| 表しやすいもの | 何者か | 何ができるか |
ドラゴンボール風にたとえると、抽象クラスは「戦士としての共通の土台」です。
たとえば、名前、戦闘力、修行する処理のような共通状態や共通処理を持たせたい場合に向いています。
一方、インターフェイスは「能力や役割の約束」です。
たとえば、気を解放できる、戦闘装備を示せる、飛べる、仲間を回復できる、といった約束を表します。
| 使いたい場面 | 向いているもの |
|---|---|
| 共通の状態や処理を持たせたい | 抽象クラス |
| 複数の能力や約束を持たせたい | インターフェイス |
| 1つの親として土台を作りたい | 抽象クラス |
| 複数の役割を同時に表したい | インターフェイス |
この違いを意識すると、インターフェイスの複数実装が、なぜ多重継承の考え方につながるのかが見えてきます。
図:クラス継承とインターフェイス複数実装の違い

この図が示していること
この図では、クラス継承とインターフェイス複数実装の違いを比較しています。
左側では、クラス継承は親クラスを1つだけ持てることを表しています。
複数の親クラスから1つの子クラスへ継承する形にはバツ印が付いています。
右側では、SuperSaiyanGuardian が iKiUser と iBattleArmor の2つのインターフェイスを実装しています。
これは、複数の親クラスを持っているのではありません。
複数の約束を引き受けている状態です。
| しくみ | できること |
|---|---|
| extends | 親クラスを1つだけ指定できる |
| implements | 複数のインターフェイスを指定できる |
この図から分かることは、Javaはクラスの構造を1本に保ちながら、インターフェイスによって複数の能力や役割を表現しているということです。
オブジェクト指向らしい自然な設計につながる
オブジェクト指向では、クラスを「何者か」で整理するだけでなく、「何ができるか」で整理することも大切です。
SuperSaiyanGuardian は、スーパーサイヤ人守護戦士という具体的な存在です。
しかし、それだけでなく、次のような能力や役割を持っています。
| 見方 | 内容 |
|---|---|
| 何者か | SuperSaiyanGuardian |
| 何ができるか | releaseKi() で気を解放できる |
| 何ができるか | showArmor() で戦闘装備を示せる |
この「何ができるか」を表すのがインターフェイスです。
インターフェイスを使うと、現実の考え方に近い形でクラスを整理できます。
ドラゴンボール風にたとえると、1人の戦士は「スーパーサイヤ人守護戦士である」という存在としての分類を持ちながら、次のような複数の役割も持てます。
| 役割 | 内容 |
|---|---|
| 気を解放する | 戦闘力を高める |
| 装備を示す | バトルジャケットの情報を表示する |
| 飛行する | 空中移動する |
| 仲間を支援する | 回復や補助を行う |
Javaでは、この複数の役割をインターフェイスで表現できます。
ドラゴンボール風にインターフェイスの複数実装を整理する
Javaでは、1つのクラスが複数の親クラスを持つことはできません。
つまり、クラスの多重継承はできません。
しかし、1つのクラスが複数のインターフェイスを実装することはできます。
ドラゴンボール風にたとえると、1人の戦士が複数の親を持つのではありません。
その代わりに、複数の能力や役割の約束を持つことができます。
| Javaのしくみ | ドラゴンボール風のイメージ |
|---|---|
| クラスの親は1つ | 戦士の系譜は1本 |
| インターフェイスは複数実装できる | 複数の奥義契約や能力を持てる |
| iKiUser | 気を解放する約束 |
| iBattleArmor | 戦闘装備を示す約束 |
| SuperSaiyanGuardian | 両方の約束を守る具体的な戦士 |
つまり、インターフェイスによる複数実装は、
親クラスを増やすのではなく、守るべき約束を増やすことで、多重継承の考え方を安全に表現するしくみ
です。
この感覚がつかめると、Javaがなぜクラスの多重継承を認めず、それでもインターフェイスで柔軟さを残しているのかが自然に見えてきます。
この内容で押さえておきたいポイント
| ポイント | 内容 |
|---|---|
| Javaのクラス継承 | 親クラスは1つだけ |
| クラスの多重継承 | Javaではできない |
| インターフェイスの複数実装 | 1つのクラスで複数指定できる |
| 書き方 | implements インターフェイス名1, インターフェイス名2 |
| 実装クラスの責任 | すべてのインターフェイスのメソッドを定義する |
| インターフェイスの役割 | 能力や約束を表す |
| 抽象クラスとの違い | 抽象クラスは共通の土台、インターフェイスは共通の約束 |
| 多重継承の考え方 | 複数の約束を同時に引き受ける形で一部を実現する |
インターフェイスの複数実装を使うと、1つのクラスに複数の役割を持たせられます。
SuperSaiyanGuardian は、iKiUser の約束も iBattleArmor の約束も守ります。
そのため、releaseKi() で気を解放でき、showArmor() で戦闘装備の情報も表示できます。
Javaでは親クラスを複数持つことはできません。
しかし、インターフェイスを使えば、複数の能力や約束を安全に組み合わせることができます。
