【Java OOP】interfaceとは?実装(implements)で学ぶ「振る舞いの契約」 更新日: 2026年1月29日 私がまだJavaの初心者だった頃、ゲームのキャラクターを作っていて大きな壁にぶつかりました。 「犬(Dog)」クラスを作って、「ロボット(Robot)」クラスを作ったまでは良かったのですが、次に「ロボット犬」を作ろうとした時です。 class RobotDog extends Dog, Robot ... と書いた瞬間、コンパイラに怒られました。 「Javaは多重継承(親を2つ持つこと)は禁止です!」と。 「え、じゃあどうすればいいの? 犬の機能もロボットの機能も両方欲しいのに...」と途方に暮れた私を救ってくれたのが、今回解説する「インターフェース (interface)」でした。 今日は、このインターフェースという強力な概念を、「テレビのリモコン」という身近な例えを使って、その本質から解き明かしていきます。 🤔 問題点:extends(継承)だけでは世界は表現できない まず、なぜinterfaceが必要なのかを知るために、extendsだけが持つ限界を見てみましょう。 Javaのクラスは、たった一つの親クラスしかextends(継承)できません(これを単一継承と言います)。 例えば、DogクラスはAnimalクラスを継承できますが、同時にRobotクラスを継承して「ロボット犬」になることはできません。 しかし、世の中には「Aであり、かつBでもある」という性質を持つものはたくさんあります。 「スマートフォン」は「電話」であると同時に、「カメラ」でもあり、「音楽プレーヤー」でもあります。 この「〜できる(能力)」という振る舞いを、クラスの親子関係(血縁)とは別に表現する仕組みが必要なのです。 📺 解決策:interfaceという「リモコンの設計図」 インターフェースとは、メソッドの具体的な処理は一切書かず、メソッド名、引数、戻り値の型だけを定義した「機能のリスト」です。 これは、ボタンの配置だけが決まっている「リモコンの設計図」によく似ています。 // 「リモコン」というインターフェース(契約書)を定義 public interface RemoteControl { // このインターフェースを実装するクラスは、 // 以下の3つの機能を必ず持たなければならない、と約束させる。 void powerOn(); // 電源を入れる機能 void volumeUp(); // 音量を上げる機能 void volumeDown(); // 音量を下げる機能 } 💡【重要】extends と implements の違い extends は「is-a」の関係(犬は動物である)を表す継承です。親子関係であり、子は親の資産を引き継ぎます。 implements は「can-do」の関係(テレビは電源オンできる)を表す実装です。契約関係であり、そのクラスが特定の「能力」を持っていることを保証します。 🛠️ 実装:implementsで契約を履行する このRemoteControlインターフェースを使って、具体的なテレビのクラスを作ってみましょう。 インターフェースをimplementsしたクラスは、そのインターフェースで定義された全てのメソッドを、具体的な処理({...})と共に実装する義務を負います。 // Sony製のテレビクラス class SonyTV implements RemoteControl { private int volume = 10; @Override public void powerOn() { System.out.println("SONY: Power ON. Welcome!"); } @Override public void volumeUp() { volume++; System.out.println("SONY: Volume -> " + volume); } @Override public void volumeDown() { volume--; System.out.println("SONY: Volume -> " + volume); } } // Samsung製のテレビクラス class SamsungTV implements RemoteControl { private int volumeLevel = 5; @Override public void powerOn() { System.out.println("Samsung TV: Turning on..."); } @Override public void volumeUp() { volumeLevel += 2; // Samsungは音量が2ずつ上がる System.out.println("Samsung TV: Current Volume is " + volumeLevel); } @Override public void volumeDown() { volumeLevel -= 2; System.out.println("Samsung TV: Current Volume is " + volumeLevel); } } SonyTVもSamsungTVも、同じRemoteControl契約を履行していますが、その中身の実装は全く異なります。これがインターフェースの強力な点です。 ✨ インターフェースの真価:ポリモーフィズム インターフェースが本当に輝くのは、ポリモーフィズム(多態性)と組み合わせた時です。 `RemoteControl`という「型」として、SonyTVもSamsungTVも同じように扱うことができるのです。 public class LivingRoom { public static void main(String[] args) { // リモコン(インターフェース型)の変数に、 // SonyTV(実装クラス)のオブジェクトを入れる RemoteControl sonyRemote = new SonyTV(); // 同じく、SamsungTVのオブジェクトも入れられる RemoteControl samsungRemote = new SamsungTV(); // 操作する側は、中身がSony製かSamsung製かを知る必要がない // ただ「リモコン」として、契約されたボタンを押すだけ operateTV(sonyRemote); System.out.println("---"); operateTV(samsungRemote); } // 引数で「リモコン」というインターフェースを受け取るメソッド public static void operateTV(RemoteControl remote) { remote.powerOn(); remote.volumeUp(); remote.volumeUp(); remote.volumeDown(); } } operateTV メソッドは、中身が何であろうと RemoteControl インターフェースを実装していることさえ知っていれば、安心して powerOn() や volumeUp() を呼び出すことができます。 将来、PanasonicTV という新しいクラスができても、operateTV メソッドを一切変更する必要はありません。 これこそが、私が「ロボット犬」を作ろうとしていた時に必要だった、柔軟で拡張性の高い設計なのです。 まとめ インターフェースは、Javaのオブジェクト指向を支える、非常に強力でエレガントな仕組みです。 interfaceは、実装すべきメソッドを定義した「契約書」である。 クラスはimplementsキーワードで、複数のインターフェースが持つ「能力」を実装できる。(多重継承の代替) インターフェースを型として使うことで、ポリモーフィズムが実現でき、柔軟で拡張性の高いコードが書ける。 extendsが「血の繋がり」を表すなら、implementsは「資格や免許」を表します。 この2つの関係を正しく理解し、使い分けることができた時、あなたのJavaの設計スキルは、間違いなく次のレベルへと到達するでしょう。 プログラミング学習に必須ツール! 記事で紹介したコードがよく分からなかったり、ご自身のコードについてもっと知りたい場合は、AIコード解説ツールが便利です。コードを貼り付けるだけで、AIが日本語で分かりやすく解説します。 AIコード解説ツールを使ってみる →