【PHP】レッスン5-08:インターフェースを理解しよう

記事内に商品プロモーションを含む場合があります

この記事で学べる知識:インターフェース

この記事の練習問題を解くために必要な知識:
基礎文法・制御構造・関数・データ構造(レッスン1~4)クラスの定義と使用コンストラクタアクセス修飾子とカプセル化クラスメンバクラスの継承メソッドのオーバーライド抽象クラスインターフェーストレイト

オブジェクト指向プログラミングでは、異なるクラス間で共通の動作を定義するために「インターフェース」が使われます。

インターフェースを利用すると複数のクラスが同じメソッドを実装できるようになり、コードの再利用性と保守性が向上します。

本記事ではPHPのインターフェースについて基本概念や使い方を解説します。

<<前のページ PHP記事一覧 次のページ>>

インターフェースとは?

【初心者向け】PHPのオブジェクト指向を分かりやすくまとめた概念図。 特にクラスの継承、オーバーライド、抽象クラス、インターフェース、トレイトの関係性を視覚的に理解できるようまとめている。

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

インターフェースにはメソッドのシグネチャ(名前や引数の定義)だけが含まれ、実装は記述されません。

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

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

インターフェースの基本構文

PHPでインターフェースを定義する基本構文は以下の通りです。

interface SampleInterface {        // SampleInterfaceという名前のインターフェースの定義
    public function methodA();     // メソッド
    public function methodB($arg); // メソッド
}
class SampleClass implements SampleInterface { // インターフェースを実装したクラスの定義
    public function methodA() {
        echo "Method A".PHP_EOL;
    }

    public function methodB($arg) {
        echo "Method B: $arg".PHP_EOL;
    }
}

ここではSampleClassSampleInterfaceを実装し、指定されたメソッドを定義しています。

  • interface:インターフェースを定義するキーワード。
  • public function:メソッドのシグネチャを定義します。インターフェース内のメソッドは常にpublicです。
  • implements:インターフェースをクラスに適用するキーワード。

インターフェースの中に定義されたメソッドは自動的に抽象メソッドとして扱われます。
ただし抽象クラス内の抽象メソッドと違いabstractキーワードは不要な点に注意しましょう。

インターフェースの使用例と解説

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

interface Animal {
    public function makeSound();
}

class Dog implements Animal {
    public function makeSound() {
        echo "Bark".PHP_EOL; // 犬の鳴き声を出力
    }
}

class Cat implements Animal {
    public function makeSound() {
        echo "Meow".PHP_EOL; // 猫の鳴き声を出力
    }
}

function playSound(Animal $animal) {
    $animal->makeSound(); // 引数がAnimalインターフェースを実装している場合に実行
}

// インスタンス生成
$dog = new Dog();
$cat = new Cat();

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

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

まとめ

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からコードを組み立てることが難しい場合は、以下のヒントを開いて参考にしましょう。

ヒント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ブロックによる例外処理
  □ 例外発生時にエラーメッセージを出力

ヒント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;
}

以上がこの問題の穴埋めコードです。

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



練習問題の解答と解説

この問題の一つの正解例とそのコードの解説を以下に示します。

正解コードの例

例えば以下のようなプログラムが考えられます。

<?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;
}

正解コードの解説

このコードはPHPのインターフェースを使って簡単な計算機を作成するプログラムです。

インターフェースの基本的な使い方を学びつつ、実際に計算機能を実装して動作させることで理解を深めます。

以下では、コードの各部分について詳しく解説します。

インターフェースの定義

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のインターフェースを使用して計算機の動作を設計しました。

インターフェースのポイント:

  • インターフェースは、共通の機能をクラスに強制するための「設計図」です。
  • 複数のクラスで共通のメソッド名や構造を保持するために役立ちます。

学習のポイント:

  • インターフェースを使うと、クラスが特定の機能を実装することを保証できます。
  • 実際の計算機能はクラスで実装し、インターフェースを利用することでコードの再利用性と保守性を高めることができます。
  • 例外処理を組み込むことで、安全で信頼性の高いプログラムを作成できます。
<<前のページ PHP記事一覧 次のページ>>

この記事への質問・コメント

この記事を作成するにあたりAIを活用しています。

問題ないことは確認していますが、もし間違いや表現の違和感などありましたら、ご指摘頂けると大変助かります。






    PHPのテキスト&問題集トップへ戻る
    トップページへ戻る