【PHP】Lesson5-8:インターフェースを理解しよう

ながみえ

一つ前のレッスンでは 抽象クラス について学習しました。

今回は インターフェース について見ていきましょう。

Lesson1:基礎文法編
Lesson2:制御構造編
Lesson3:関数編
Lesson4:データ構造編
Lesson5:クラス

 ・Lesson5-1:クラスを定義しよう
 ・Lesson5-2:コンストラクタを理解しよう
 ・Lesson5-3:アクセス修飾子とカプセル化を理解しよう
 ・Lesson5-4:クラスメンバを理解しよう
 ・Lesson5-5:クラスの継承を理解しよう
 ・Lesson5-6:メソッドのオーバーライドを理解しよう
 ・Lesson5-7:抽象クラスを理解しよう
 ・Lesson5-8:インターフェースを理解しよう ◁今回はココ
 ・Lesson5-9:トレイトを理解しよう
 ・確認問題5-1:モンスター捕獲ゲームを作ろう
 ・確認問題5-2:マインスイーパを作ろう

<<前のページ

学習記事一覧

次のページ>>

PHPインターフェースの基本と実装方法

PHPのインターフェースは、クラス同士の共通ルールを定義し、コードの拡張性や再利用性を高めるための重要な仕組みです。

これを理解すれば、複数のクラスで同じメソッド構造を共有したり、設計パターンを意識した柔軟なプログラムを組めるようになります。

特にimplementsを使った実装方法や、抽象クラスとの違いを押さえることで、オブジェクト指向設計の幅が一気に広がります。

この記事では、初心者でもわかるようにインターフェースの基本概念から実装手順、実用的なサンプルコードや計算機演習までを丁寧に解説します。

それではさっそく、インターフェースの世界を学んでいきましょう。

インターフェースとは?|共通動作を定義する仕組みと基本構文

インターフェースとは、クラスが実装しなければならないメソッドの「ひな型」を定義する仕組みです。

インターフェースには抽象メソッドだけが含まれ、実装は記述されません。

これにより、インターフェースを実装するクラスは、必ず指定されたメソッドを実装しなければならなくなります。

インターフェースは多くのクラスに共通の機能を強制することで、プログラムの一貫性を保つのに役立ちます。

PHPでインターフェースを定義するには、interfaceキーワードimplementsキーワード を使用します。

interface インターフェース名 {			 // インターフェースの定義
    public function 抽象メソッド1();		// 抽象メソッドの定義
    public function 抽象メソッド2(引数);  // 引数を持つ抽象メソッドの定義
}
class クラス名 implements インターフェース名 {	// インターフェースを実装したクラスの定義
    public function 抽象メソッド1() {			  // 抽象メソッド1のオーバーライド
        // 処理内容
    }
    public function 抽象メソッド2(引数) {		// 抽象メソッド1のオーバーライド
        // 処理内容
    }
}

このように、インターフェースの中に定義されたメソッドは自動的に抽象メソッドとして扱われます。

ただし抽象クラス内の抽象メソッドと違いabstractキーワードは不要な点に注意しましょう。

インターフェースを実装したコード例

以下は、インターフェースを使った具体的な例です。

<?php
interface Animal {					// インターフェースの定義
    public function makeSound();	// 抽象メソッドの定義
}
class Dog implements Animal {		// インターフェースを実装したDogクラスの定義
    public function makeSound() {	// オーバーライド
        echo "わんわん!".PHP_EOL;	// 犬の鳴き声を出力
    }
}
class Cat implements Animal {			// インターフェースを実装したCatクラスの定義
    public function makeSound() {		// オーバーライド
        echo "にゃーにゃー!".PHP_EOL;   // 猫の鳴き声を出力
    }
}
function playSound(Animal $animal) {	// 引数をAnimal型に型指定して関数の定義
    $animal->makeSound();	// 引数がAnimalインターフェースを実装している場合に実行
}

$dog = new Dog();	// インスタンス生成
$cat = new Cat();	// インスタンス生成
playSound($dog);	// "わんわん!" と出力
playSound($cat);	// "にゃーにゃー!" と出力
  1. 共通の機能を強制AnimalインターフェースはmakeSoundメソッドを強制します。
  2. 柔軟性:異なる動作(BarkMeow)をクラスごとに自由に定義できます。
  3. 型指定による安全性playSound関数はAnimalインターフェースを引数に指定しているため、Animalを実装していないクラスは使用できません。

このようにインターフェースはコードの一貫性を保ちながら多態性(ポリモーフィズム)を実現します。

関数の型指定(型付け)について復習したい方は↓↓の記事を参考にしてください。

あわせて読みたい
【PHP】Lesson3-5:関数の型付けを理解しよう
【PHP】Lesson3-5:関数の型付けを理解しよう

インターフェースと抽象クラスの違いを表で紹介

ンターフェースと抽象クラスは、抽象メソッドを用いて「設計の契約」を作る点は同じですが、役割と制約が違います。

それぞれの特徴と違いを表にまとめましたので確認してください。

項目インターフェース (interface)抽象クラス (abstract class)
目的できることの契約(APIの約束)共通処理+契約(設計図+部品)
インスタンス化できないできない
継承/実装数複数実装OK単一継承のみ
メソッドの本体持てない(宣言のみ)持てる(通常メソッドOK)
抽象メソッド宣言できる(暗黙に抽象)宣言できる(abstract
アクセス修飾子メソッドは基本 publicpublic/protected/private 使える
プロパティ定義不可定義可(状態を持てる)
コンストラクタ宣言はできる(実装はクラス側)実装できる
定数定義可(const定義可(const
使いどころ実装を縛りたい・共通処理不要共通処理や状態を持たせたい

使い分けとしては、共通処理やプロパティが必要なら抽象クラス、純粋に「このメソッド群を必ず持て」ならインターフェースとなります。

また、クラスは1つしか継承できない(多重継承不可)が、インターフェースは複数実装できる点も重要な違いです。

まとめ|インターフェースの理解を深めよう

今回の学習では、PHPのインターフェースについて、その役割・基本構文・実装方法を理解し、抽象クラスとの違いも整理しました。

これにより、複数のクラスで共通のメソッド仕様を統一し、保守性や拡張性を高める設計ができるようになったはずです。

サンプルコードを通じて、implementsキーワードの使い方や、実際のプロジェクトでの利用イメージも掴めたと思います。

特に「抽象クラスとインターフェースの使い分け」を意識できるようになったことは、今後のオブジェクト指向設計の大きな武器になります。

次のレッスンでは、この知識を活かしながら、より複雑な設計パターンに挑戦していきましょう。

少しずつ積み重ねることで、PHPで作れる世界が大きく広がります。

演習問題|インターフェースを使って計算機を実装しよう

PHPのインターフェースを使った簡単な計算機プログラムを作成しましょう。

このプログラムではユーザーが入力した2つの数値に対して、加算、減算、乗算、除算を行います。

またインターフェースを利用して計算機の機能を定義し、異なる計算ロジックを実装する方法を学びます。

さらに0で割った場合にはエラーメッセージを表示し、プログラムが停止しないようにします。

この演習の要件

以下の要件に従ってコードを完成させてください。

  1. インターフェース
    Calculatorというインターフェースを定義し、以下の4つのメソッドを宣言すること。
    1. 加算:add($a, $b)
    2. 減算:subtract($a, $b)
    3. 乗算:multiply($a, $b)
    4. 除算:divide($a, $b)
  2. クラスの実装
    BasicCalculatorというクラスを作成し、Calculatorインターフェースを実装すること。
    各メソッドでは、計算結果を返すように実装すること。
    除算メソッドでは、0で割ろうとした場合に例外をスローすること。
  3. ユーザー入力と出力
    標準入力を使って2つの数値を受け取ること。
    加算、減算、乗算、除算の結果をそれぞれ出力すること。
  4. エラーハンドリング
    0で割る場合は例外をキャッチし、エラーメッセージを表示すること。

ただし、以下のような実行結果となること。

1つ目の数値を入力してください:
10
2つ目の数値を入力してください:
2
加算結果: 12
減算結果: 8
乗算結果: 20
除算結果: 5

解き方のヒント

1からコードを組み立てることが難しい場合は、以下のヒントを開いて参考にしましょう。

Q
ヒント1【コードの構成を見る】

正解のコードは上から順に以下のような構成となっています。
(※下記の□はコード内のインデントを表しています)

1:PHPコードの開始宣言
2:Calculatorインターフェースの定義
  □ 加算メソッドaddを宣言
  □ 減算メソッドsubtractを宣言
  □ 乗算メソッドmultiplyを宣言
  □ 除算メソッドdivideを宣言
3:BasicCalculatorクラスの定義
  □ Calculatorインターフェースを実装
  □ addメソッドを実装し、引数aとbの和を返す
  □ subtractメソッドを実装し、引数aとbの差を返す
  □ multiplyメソッドを実装し、引数aとbの積を返す
  □ divideメソッドを実装し、引数bが0の場合に例外を投げる
  □ □ 0以外の場合はaとbの商を返す
4:getInput関数の定義
  □ 引数promptを受け取り、プロンプトを表示
  □ 標準入力から値を取得し、空白を除去
  □ 取得した値をfloat型に変換して返す
5:tryブロックによるメイン処理開始
  □ BasicCalculatorのインスタンスを作成し、変数calcに格納
  □ getInput関数を使って1つ目の数値を入力し、変数num1に格納
  □ getInput関数を使って2つ目の数値を入力し、変数num2に格納
  □ 加算結果を計算し出力
  □ 減算結果を計算し出力
  □ 乗算結果を計算し出力
  □ 除算結果を計算し出力
6:catchブロックによる例外処理
  □ 例外発生時にエラーメッセージを出力

Q
ヒント2【穴埋め問題にする】

以下のコードをコピーし、コメントに従ってコードを完成させて下さい。

<?php
/*【穴埋め問題1】
ここで計算操作を定義するインターフェースCalculatorを作成し、加算、減算、乗算、除算のメソッドを定義してください。
*/

/*【穴埋め問題2】
ここでCalculatorインターフェースを実装するBasicCalculatorクラスを作成してください。
その中で各メソッド(add、subtract、multiply、divide)を実装してください。
*/

// ユーザー入力から数値を取得する関数
function getInput($prompt) {
    echo $prompt . PHP_EOL; // プロンプト表示
    $input = trim(fgets(STDIN)); // 入力取得
    return (float)$input; // 数値として返す
}

// メイン処理
try {
    /*【穴埋め問題3】
    ここでBasicCalculatorクラスのインスタンスを作成してください。
    */

    // ユーザーから2つの数値を入力
    $num1 = getInput("1つ目の数値を入力してください:");
    $num2 = getInput("2つ目の数値を入力してください:");

    // 計算結果の表示
    echo "加算結果: " . $calc->add($num1, $num2) . PHP_EOL;
    echo "減算結果: " . $calc->subtract($num1, $num2) . PHP_EOL;
    echo "乗算結果: " . $calc->multiply($num1, $num2) . PHP_EOL;
    echo "除算結果: " . $calc->divide($num1, $num2) . PHP_EOL;

} catch (Exception $e) {
    // エラーが発生した場合の処理
    echo "エラー: " . $e->getMessage() . PHP_EOL;
}

このヒントを見てもまだ回答を導き出すのが難しいと感じる場合は、先に正解のコードと解説を見て内容を理解するようにしましょう。

演習問題の答え合わせ

この問題の正解コードとその解説は以下の通りです。

クリックして開いて確認してください。

Q
正解コード
<?php
// 計算操作を定義するインターフェース
interface Calculator {
    // 加算メソッドの定義
    public function add($a, $b);

    // 減算メソッドの定義
    public function subtract($a, $b);

    // 乗算メソッドの定義
    public function multiply($a, $b);

    // 除算メソッドの定義
    public function divide($a, $b);
}

// BasicCalculatorクラス:Calculatorインターフェースを実装する
class BasicCalculator implements Calculator {
    // 加算の実装
    public function add($a, $b) {
        return $a + $b;
    }

    // 減算の実装
    public function subtract($a, $b) {
        return $a - $b;
    }

    // 乗算の実装
    public function multiply($a, $b) {
        return $a * $b;
    }

    // 除算の実装
    public function divide($a, $b) {
        // 0で割る場合はエラーメッセージを表示
        if ($b == 0) {
            throw new Exception("0で割ることはできません。");
        }
        return $a / $b;
    }
}

// ユーザー入力から数値を取得する関数
function getInput($prompt) {
    echo $prompt . PHP_EOL; // プロンプト表示
    $input = trim(fgets(STDIN)); // 入力取得
    return (float)$input; // 数値として返す
}

// メイン処理
try {
    $calc = new BasicCalculator(); // 計算機のインスタンス作成

    // ユーザーから2つの数値を入力
    $num1 = getInput("1つ目の数値を入力してください:");
    $num2 = getInput("2つ目の数値を入力してください:");

    // 計算結果の表示
    echo "加算結果: " . $calc->add($num1, $num2) . PHP_EOL;
    echo "減算結果: " . $calc->subtract($num1, $num2) . PHP_EOL;
    echo "乗算結果: " . $calc->multiply($num1, $num2) . PHP_EOL;
    echo "除算結果: " . $calc->divide($num1, $num2) . PHP_EOL;

} catch (Exception $e) {
    // エラーが発生した場合の処理
    echo "エラー: " . $e->getMessage() . PHP_EOL;
}
Q
正解コードの解説

コードをブロックごとに分割して解説します。

インターフェースの定義

interface Calculator {
    public function add($a, $b);
    public function subtract($a, $b);
    public function multiply($a, $b);
    public function divide($a, $b);
}
  • interface Calculator
    インターフェースを定義するためのキーワードです。このインターフェースでは、計算機に必要な4つの操作(加算、減算、乗算、除算)を定義しています。
  • メソッドの宣言
    各メソッドは名前と引数のみを定義し、処理内容は記述していません。このようにインターフェースは「設計図」として働き、具体的な処理はクラスで実装します。
  • ポイント:
    インターフェースを使うことで、異なるクラスが同じメソッドを実装しなければならないというルールを強制できます。これにより、コードの一貫性と再利用性が向上します。

クラスの実装

class BasicCalculator implements Calculator {
    public function add($a, $b) {
        return $a + $b;
    }

    public function subtract($a, $b) {
        return $a - $b;
    }

    public function multiply($a, $b) {
        return $a * $b;
    }

    public function divide($a, $b) {
        if ($b == 0) {
            throw new Exception("0で割ることはできません。");
        }
        return $a / $b;
    }
}
  1. class BasicCalculator implements Calculator
    クラスBasicCalculatorはインターフェースCalculatorを実装します。implementsは「実装する」という意味で、インターフェースで定義されたすべてのメソッドを実装する義務を与えます。
  2. 各メソッドの実装
    • 加算、減算、乗算はそれぞれ単純な数値計算を行います。
    • 除算では、0で割る場合の例外処理を追加しています。これにより、エラー発生時にプログラムが停止しないように対処できます。
  3. 例外処理:
    • throw new Exceptionはエラー時に特定のメッセージを表示してプログラムを安全に終了させます。

ユーザー入力と関数の処理

function getInput($prompt) {
    echo $prompt . PHP_EOL;
    $input = trim(fgets(STDIN));
    return (float)$input;
}
  • 関数定義:ユーザーからの入力を受け取る関数getInputを定義しています。
  • fgets(STDIN)標準入力からデータを取得します。コンソールでユーザーに数値を入力してもらう仕組みです。
  • trim()入力された文字列の前後の余分な空白や改行を取り除きます。
  • (float)入力された値を数値に変換します。これにより、文字列ではなく数値として計算に使用できます。

メイン処理とエラーハンドリング

try {
    $calc = new BasicCalculator();

    $num1 = getInput("1つ目の数値を入力してください:");
    $num2 = getInput("2つ目の数値を入力してください:");

    echo "加算結果: " . $calc->add($num1, $num2) . PHP_EOL;
    echo "減算結果: " . $calc->subtract($num1, $num2) . PHP_EOL;
    echo "乗算結果: " . $calc->multiply($num1, $num2) . PHP_EOL;
    echo "除算結果: " . $calc->divide($num1, $num2) . PHP_EOL;

} catch (Exception $e) {
    echo "エラー: " . $e->getMessage() . PHP_EOL;
}
  • tryブロック:エラーが発生する可能性があるコードを安全に実行します。
  • catchブロック:エラーが発生した場合に例外をキャッチし、エラーメッセージを表示します。これによりプログラムがクラッシュすることを防ぎます。
  • 実行の流れ
    1. 計算機オブジェクトを作成します。
    2. ユーザーから2つの数値を入力します。
    3. 各計算結果を順番に表示します。
    4. 0で割った場合には例外が発生し、エラーメッセージが表示されます。
もっと分かりやすい学習サイトにするために

この記事を読んで「ここが分かりにくかった」「ここが難しかった」等の意見を募集しています。

世界一わかりやすいPHP学習サイトにするため、ぜひ 問い合わせフォーム からご意見下さい。

<<前のページ

学習記事一覧

次のページ>>

記事URLをコピーしました