
Java道|インターフェイスで実現する多重継承
親クラスは1つだけでも、守る約束は複数持てる。
インターフェイスを使うと、Javaでは多重継承の考え方を安全で分かりやすい形にできます。
ここまで、クラスの継承、抽象クラス、インターフェイスを順番に学んできました。
継承を使うと、親クラスの機能を子クラスへ受け継がせることができます。
抽象クラスを使うと、共通の土台を作りながら、未完成の処理を子クラスに任せることができます。
インターフェイスを使うと、クラスに「このメソッドを必ず持つ」という共通の約束を持たせることができます。
ここで次に気になるのが、
1つのクラスに複数の性質や約束を持たせたい場合はどうするのか
という点です。
鬼滅の刃風にたとえると、1人の和風剣士は、1つの特徴だけで成り立っているわけではありません。
たとえば、ある剣士は次のような複数の性質を持っているかもしれません。
| 性質 | 鬼滅の刃風のイメージ |
|---|---|
| 剣士である | 戦闘できる |
| 情報を表示できる | 自分の名前や戦闘力を示せる |
| 防具を持つ | 羽織や鎧の情報を示せる |
| 特殊能力を使える | 呼吸や支援技を使える |
しかし、Javaでは、1つのクラスが複数のスーパークラスを同時に継承することはできません。
つまり、クラスそのものの多重継承は認められていません。
そこで登場するのが インターフェイスの複数実装 です。
Javaでは、クラスの親クラスは1つだけですが、インターフェイスは複数実装できます。
これにより、1つのクラスに複数の「約束」や「能力のルール」を持たせられます。
鬼滅の刃風にたとえると、
「この剣士は、戦士として情報を示す約束も守るし、防具情報を示す約束も守る」
と宣言できるようなものです。
Javaではクラスの多重継承はできない
まず、出発点をはっきりさせましょう。
Javaでは、1つのクラスが2つ以上のスーパークラスを同時に継承することはできません。
たとえば、次のような2つのクラスがあるとします。
class Slayer
{
}
class ArmorUser
{
}この2つを同時に親クラスとして持つように、次のような書き方はできません。
// これはできない
class WaterPillar extends Slayer, ArmorUser
{
}Javaのクラス継承では、extends のあとに指定できる親クラスは1つだけです。
| 書き方 | Javaで可能か | 理由 |
|---|---|---|
| class WaterPillar extends Slayer | 可能 | 親クラスが1つだけ |
| class WaterPillar extends Slayer, ArmorUser | 不可能 | 親クラスを複数指定している |
鬼滅の刃風にたとえると、1人の剣士クラスが「剣士の基本クラス」と「防具使いの基本クラス」を、同時に親として持つことはできないということです。
Javaは、クラスの親子関係を1本の系譜として整理します。
そのため、クラスの継承では多重継承を禁止しています。
なぜクラスの多重継承はできないのか
クラスの多重継承ができると、一見とても便利そうに見えます。
しかし、複数の親クラスを同時に持つと、設計が複雑になりやすいです。
たとえば、2つの親クラスが同じ名前のメソッドを持っていたらどうでしょうか。
class Slayer
{
void show()
{
System.out.println("剣士の情報を表示します。");
}
}
class ArmorUser
{
void show()
{
System.out.println("防具使いの情報を表示します。");
}
}もし、1つのクラスがこの2つを同時に継承できた場合、show() を呼び出したときに、どちらの show() を使うのか分かりにくくなります。
| 起こりやすい問題 | 内容 |
|---|---|
| 同名メソッドの衝突 | どちらの親のメソッドを使うか迷う |
| 同名フィールドの衝突 | どちらの値を指すのか分かりにくい |
| 初期化順序が複雑 | どの親クラスを先に初期化するのか迷う |
| 設計が読みにくい | クラスの責任範囲があいまいになる |
鬼滅の刃風にたとえると、1人の剣士が2つの流派の基本型を同時に親として持ち、両方に同じ名前の奥義がある状態です。
そのとき、同じ奥義名を呼んだら、どちらの流派の奥義が出るのか分かりにくくなります。
Javaは、このような混乱を避けるために、クラスの親は1つだけというルールにしています。
↓クリックすると拡大表示されます。

それでも複数の性質を持たせたい場面はある
ただし、現実の設計では、1つのクラスが複数の性質や能力を持つことは自然です。
鬼滅の刃風に考えると、ある剣士は次のような複数の特徴を持っているかもしれません。
| 持たせたい性質 | 例 |
|---|---|
| 剣士として情報を表示できる | 名前や戦闘力を表示する |
| 防具情報を表示できる | 羽織や鎧の情報を表示する |
| 飛行できる | 空中移動できる |
| 支援できる | 仲間を回復・補助できる |
もしクラスの継承だけに頼ると、これらを柔軟に組み合わせるのが難しくなります。
そこで Java は、クラスの多重継承は許さない代わりに、インターフェイスの複数実装 を用意しています。
つまり、Javaは次のように役割を分けています。
| しくみ | 役割 |
|---|---|
| クラスの継承 | 親クラスは1つだけにして、構造を整理する |
| インターフェイスの実装 | 複数の能力や約束を持たせる |
このように、Javaは分かりやすさと柔軟さを両立しています。
インターフェイスの複数実装とは何か
Javaでは、1つのクラスが2つ以上のインターフェイスを実装できます。
このときは、implements のあとにインターフェイス名をカンマで並べます。
基本の形は次のとおりです。
class クラス名 implements インターフェイス名1, インターフェイス名2
{
}たとえば、鬼滅の刃風に、次の2つのインターフェイスがあるとします。
| インターフェイス | 役割 |
|---|---|
| iSlayer | 剣士としての情報を表示する約束 |
| iArmor | 防具情報を表示する約束 |
この2つを、1つの WaterPillar クラスが実装できます。
class WaterPillar implements iSlayer, iArmor
{
}これは、WaterPillar クラスが次の2つの約束を同時に引き受けるという意味です。
| 引き受ける約束 | 必要なメソッド |
|---|---|
| iSlayer の約束 | sShow() |
| iArmor の約束 | aShow() |
鬼滅の刃風にたとえると、WaterPillar は、
「剣士として情報を示せる」
「防具の情報も示せる」
という2つの役割を同時に持つことになります。
なぜこれが多重継承の一部と言えるのか
ここで大切なのは、インターフェイスの複数実装は、クラスそのものを複数継承しているわけではないという点です。
複数の親クラスからフィールドや具体的な処理を受け継ぐのではありません。
受け継ぐのは、主に メソッド名の約束 です。
たとえば、次のような2つのインターフェイスがあるとします。
interface iSlayer
{
void sShow();
}
interface iArmor
{
void aShow();
}この2つを実装するクラスは、sShow() と aShow() の両方を定義しなければなりません。
class WaterPillar implements iSlayer, iArmor
{
public void sShow()
{
}
public void aShow()
{
}
}つまり、複数のインターフェイスが定めたメソッド名のルールを、1つのクラスがまとめて引き受けているわけです。
| 多重継承の種類 | Javaでの扱い |
|---|---|
| 複数のクラスを同時に継承する | できない |
| 複数のインターフェイスを同時に実装する | できる |
| 複数の約束を1つのクラスに持たせる | できる |
鬼滅の刃風にたとえると、1人の剣士が複数の親を持つのではありません。
複数の任務規則や能力の約束を同時に守る、というイメージです。
だから、インターフェイスの複数実装は、Javaで多重継承の考え方の一部を安全に実現する方法だと考えられます。
複数のインターフェイスを実装する
ファイル名:Sample4.java
interface iSlayer
{
void sShow();
}
interface iArmor
{
void aShow();
}
class WaterPillar implements iSlayer, iArmor
{
private String name;
private int swordPower;
public WaterPillar(String n, int sp)
{
name = n;
swordPower = sp;
System.out.println(name + " 剣力" + swordPower + "の水柱剣士を作成しました。");
}
public void sShow()
{
System.out.println("水柱剣士の名前は" + name + "です。");
System.out.println("剣力は" + swordPower + "です。");
}
public void aShow()
{
System.out.println("水柱剣士の防具は青紋の羽織です。");
}
}
class Sample4
{
public static void main(String[] args)
{
WaterPillar slayer1 = new WaterPillar("水月", 18000);
slayer1.sShow();
slayer1.aShow();
}
}実行結果
水月 剣力18000の水柱剣士を作成しました。
水柱剣士の名前は水月です。
剣力は18000です。
水柱剣士の防具は青紋の羽織です。WaterPillar が2つのインターフェイスを実装している
このプログラムでは、WaterPillar クラスが2つのインターフェイスを実装しています。
class WaterPillar implements iSlayer, iArmorここで宣言しているのは、次の2つです。
| 実装しているもの | 意味 |
|---|---|
| iSlayer | 剣士としての情報表示の約束を守る |
| iArmor | 防具情報表示の約束を守る |
つまり WaterPillar は、iSlayer の約束も、iArmor の約束も引き受けています。
そのため、WaterPillar クラスでは、両方のインターフェイスが要求するメソッドを定義する必要があります。
| インターフェイス | 要求するメソッド | WaterPillar で定義する必要 |
|---|---|---|
| iSlayer | sShow() | 必要 |
| iArmor | aShow() | 必要 |
このように、インターフェイスを複数実装するということは、複数の約束を同時に引き受けることです。
鬼滅の刃風にたとえると、水柱剣士が「剣士として名乗る役割」と「防具情報を示す役割」の両方を持つということです。
sShow() と aShow() は何を表しているのか
この例では、2つのインターフェイスが別々の役割を持っています。
interface iSlayer
{
void sShow();
}iSlayer は、剣士としての情報を表示する約束です。
interface iArmor
{
void aShow();
}iArmor は、防具情報を表示する約束です。
WaterPillar クラスでは、この2つを次のように実装しています。
public void sShow()
{
System.out.println("水柱剣士の名前は" + name + "です。");
System.out.println("剣力は" + swordPower + "です。");
}sShow() では、剣士としての名前と剣力を表示しています。
public void aShow()
{
System.out.println("水柱剣士の防具は青紋の羽織です。");
}aShow() では、防具として青紋の羽織を表示しています。
整理すると、次のようになります。
| メソッド | 役割 | 表示内容 |
|---|---|---|
| sShow() | 剣士としての情報表示 | 名前、剣力 |
| aShow() | 防具情報の表示 | 青紋の羽織 |
同じ WaterPillar オブジェクトが、2つの異なる役割を持っていることが分かります。
なぜクラスの多重継承より扱いやすいのか
クラスの多重継承では、複数の親クラスから具体的なフィールドやメソッドを受け継ぐことになります。
そのため、同じ名前のメンバがあったときに衝突しやすくなります。
一方、インターフェイスは、主に「こういうメソッドを持つこと」という約束を表します。
そのため、役割を分けやすく、クラス構造も複雑になりにくいです。
| しくみ | 役割 |
|---|---|
| クラスの継承 | 共通の土台を受け継ぐ |
| インターフェイス | 能力や約束を追加する |
鬼滅の刃風にたとえると、クラスは「水柱剣士という存在そのもの」を表します。
インターフェイスは「剣士として情報を表示できる」「防具情報を表示できる」という能力ルールを表します。
つまり、クラスで「何者か」を表し、インターフェイスで「何ができるか」を追加しているわけです。
この整理があるので、Javaではクラスの多重継承を使わなくても、複数の能力を自然に表現できます。
インターフェイスの複数実装が便利な場面
インターフェイスの複数実装は、1つのクラスに複数の役割を持たせたいときに便利です。
鬼滅の刃風に考えると、次のような使い方ができます。
| インターフェイス | 役割 |
|---|---|
| iSlayer | 剣士として情報を表示できる |
| iArmor | 防具情報を表示できる |
| iFlyable | 空中移動できる |
| iSupporter | 仲間を支援できる |
たとえば、将来的に WaterPillar に飛行能力の約束も追加したい場合は、次のようにできます。
class WaterPillar implements iSlayer, iArmor, iFlyable
{
}このように、親クラスを増やさなくても、必要な能力の約束を増やせます。
| 目的 | インターフェイスでの表現 |
|---|---|
| 情報表示できることを保証したい | iSlayer |
| 防具情報を表示できることを保証したい | iArmor |
| 飛行できることを保証したい | iFlyable |
| 支援できることを保証したい | iSupporter |
これにより、クラスは1つの基本構造を保ちながら、能力や役割の面では柔軟に広げられます。
抽象クラスとの違いも意識しておきたい
インターフェイスの複数実装を理解するには、抽象クラスとの違いも押さえておくと分かりやすいです。
| 比較項目 | 抽象クラス | インターフェイス |
|---|---|---|
| 役割 | 共通の土台 | 共通の約束 |
| 通常フィールド | 持てる | 原則として持てない |
| 通常メソッド | 持てる | 原則として処理を書かない |
| コンストラクタ | 持てる | 持てない |
| 継承・実装 | extends で1つだけ | implements で複数可 |
| 表しやすいもの | 何者か | 何ができるか |
鬼滅の刃風にたとえると、抽象クラスは「剣士としての共通の土台」です。
たとえば、speed や setSpeed() のような共通状態・共通処理を持てます。
一方、インターフェイスは「能力や役割の約束」です。
たとえば、情報を表示できる、防具情報を表示できる、飛べる、支援できる、といった約束を表します。
| 使いたい場面 | 向いているもの |
|---|---|
| 共通の状態や処理を持たせたい | 抽象クラス |
| 複数の能力や約束を持たせたい | インターフェイス |
| 1つの親として土台を作りたい | 抽象クラス |
| 複数の役割を同時に表したい | インターフェイス |
この違いを意識すると、インターフェイスの複数実装が、なぜ多重継承の考え方につながるのかが見えてきます。
オブジェクト指向らしい自然な設計につながる
オブジェクト指向では、クラスを「何者か」で整理するだけでなく、「何ができるか」で整理することも大切です。
WaterPillar は、水柱剣士という具体的な存在です。
しかし、それだけでなく、次のような能力や役割を持っています。
| 見方 | 内容 |
|---|---|
| 何者か | WaterPillar |
| 何ができるか | sShow() で剣士情報を表示できる |
| 何ができるか | aShow() で防具情報を表示できる |
この「何ができるか」を表すのがインターフェイスです。
インターフェイスを使うと、現実の考え方に近い形でクラスを整理できます。
鬼滅の刃風にたとえると、1人の剣士は「水柱である」という存在としての分類を持ちながら、
「情報を表示できる」
「防具情報を示せる」
「仲間を支援できる」
のような複数の役割も持てます。
Javaでは、この複数の役割をインターフェイスで表現できます。
図:2つのインターフェイスを1つのクラスが実装する
↓クリックすると拡大表示されます。

この図が示していること
この図では、iSlayer と iArmor という2つのインターフェイスから、WaterPillar クラスへ約束が集まる様子を表しています。
iSlayer は sShow() という約束を持っています。
iArmor は aShow() という約束を持っています。
WaterPillar は、その両方を implements で実装しています。
| インターフェイス | 約束 | WaterPillar の責任 |
|---|---|---|
| iSlayer | sShow() を持つ | sShow() を定義する |
| iArmor | aShow() を持つ | aShow() を定義する |
この図から分かることは、Javaではクラスの多重継承はできなくても、インターフェイスを使えば複数のメソッドの約束を1つのクラスに集められるということです。
図:クラス継承とインターフェイス複数実装の違い
↓クリックすると拡大表示されます。

この図が示していること
この図では、クラス継承とインターフェイス複数実装の違いを比較しています。
左側では、クラス継承は親クラスを1つだけ持てることを表しています。
複数の親クラスから1つの子クラスへ継承する形にはバツ印が付いています。
右側では、WaterPillar が iSlayer と iArmor の2つのインターフェイスを実装しています。
これは、複数の親クラスを持っているのではなく、複数の約束を引き受けている状態です。
| しくみ | できること |
|---|---|
| extends | 親クラスを1つだけ指定できる |
| implements | 複数のインターフェイスを指定できる |
この図から分かることは、Javaはクラスの構造を1本に保ちながら、インターフェイスによって複数の能力や役割を表現しているということです。
鬼滅の刃風にインターフェイスの多重実装を整理する
Javaでは、1つのクラスが複数の親クラスを持つことはできません。
つまり、クラスの多重継承はできません。
しかし、1つのクラスが複数のインターフェイスを実装することはできます。
鬼滅の刃風にたとえると、1人の剣士が複数の親を持つのではありません。
その代わりに、複数の能力や役割の約束を持つことができます。
| Javaのしくみ | 鬼滅の刃風のイメージ |
|---|---|
| クラスの親は1つ | 剣士の系譜は1本 |
| インターフェイスは複数実装できる | 複数の任務規則や能力を持てる |
| iSlayer | 剣士情報を表示する約束 |
| iArmor | 防具情報を表示する約束 |
| WaterPillar | 両方の約束を守る具体的な剣士 |
つまり、インターフェイスによる多重実装は、
親クラスを増やすのではなく、守るべき約束を増やすことで、多重継承の考え方を表現する仕組み
です。
この感覚がつかめると、Javaがなぜクラスの多重継承を認めず、それでもインターフェイスで柔軟さを残しているのかが自然に見えてきます。
この内容で押さえておきたいポイント
| ポイント | 内容 |
|---|---|
| Javaのクラス継承 | 親クラスは1つだけ |
| クラスの多重継承 | Javaではできない |
| インターフェイスの複数実装 | 1つのクラスで複数指定できる |
| 書き方 | implements インターフェイス名1, インターフェイス名2 |
| 実装クラスの責任 | すべてのインターフェイスのメソッドを定義する |
| インターフェイスの役割 | 能力や約束を表す |
| 抽象クラスとの違い | 抽象クラスは共通の土台、インターフェイスは共通の約束 |
| 多重継承の考え方 | 複数の約束を同時に引き受ける形で一部を実現する |
インターフェイスの複数実装を使うと、1つのクラスに複数の役割を持たせられます。
WaterPillar は、iSlayer の約束も iArmor の約束も守ります。
そのため、sShow() で剣士情報を表示でき、aShow() で防具情報も表示できます。
Javaでは親クラスを複数持つことはできません。
しかし、インターフェイスを使えば、複数の能力や約束を安全に組み合わせることができます。
