はじめに
本記事は、オブジェクト指向について学習した内容をまとめています。3 つの記事に分かれており、本記事は 3 記事になります。
サンプルコードの PHP のバージョンは 8.1.20 で、開発環境に Docker を使用しています。
インターフェース
Wikipedia 引用
インタフェース (英: interface) は、Java や C#などのオブジェクト指向プログラミング言語においてサポートされる、実装を持たない抽象型のことである。これらの言語において、クラスは実装の多重継承をサポートしない代わりに、任意の数のインタフェースを実装 (implement) することができ、これにより型の多重継承をサポートする。複数の種類のオブジェクト を、インタフェースを用いた多態性によって統一的に扱うことができるようになる。インターフェイスやインターフェースなどと表記することもある
上記の内容は Java や C#で解説されていますが、PHP においても同様のことが言えます。
インターフェースとは、全てのメソッドが実装されていない仕様の集合を定義します(つまりすべて抽象メソッドである)。インタフェースは具体的な実装を一切持たず、どのようなメソッドが必要かだけを定義します。
また、インターフェースで定義したメソッドはインターフェースを実装したクラスでは必ずそのメソッドを記述しなければいけません。
これは前回解説した、抽象クラス及び抽象メソッドと同様です。
インターフェースのサンプルコードとしてIAnimal
インターフェース及びIAnimal.php
を作成します。
<?php
namespace SampleInterface;
interface IAnimal
{
// 定数を定義することが出来ます
public const BEST_SLEEP = "良質な睡眠";
// 具体的な実装を定義することは出来ません
// アクセス修飾子は必ず public にする必要があります
public function sleep(); // 動物は眠ります
}
インターフェースで定義するメソッドのアクセス修飾子はpublic
にする必要があります。また、定数も定義することが出来ます。定義された定数はメソッドと違い実装の強制はされません。
次に、IAnimal インターフェースを実装したDogクラス
及びDog.php
ファイルを作成します。
<?php
namespace SampleInterface;
use SampleInterface\IAnimal;
class Dog implements IAnimal // implements クラス名 でインターフェースを実装する
{
// インターフェースで定義されたメソッドは必ず実装する必要がある
public function sleep()
{
// インターフェース実装先クラスで処理を記述する
return "犬は 12~14 時間寝ます。";
}
}
最後にCatクラス
及びCat.php
ファイルを作成します。
<?php
namespace SampleInterface;
use SampleInterface\IAnimal;
class Cat implements IAnimal
{
public function sleep()
{
return "猫は 12~16 時間寝ます。";
}
}
これらの作成したクラスをオートローダーに登録します。オートローダーの詳細については前回の記事を参考してください。
{
"name": "hn_pgtech/sample_php_project",
"description": "PHPの機能を検証する",
"require": {},
"autoload": {
"psr-4": {
"BaseClass\\": "ObjectSample/BaseClass/",
"ExtendTrait\\": "ObjectSample/ExtendTrait/",
"SampleStatic\\": "ObjectSample/SampleStatic/",
"SampleConst\\": "ObjectSample/SampleConst/",
"SampleAbstract\\": "ObjectSample/SampleAbstract/",
+ "SampleInterface\\": "ObjectSample/SampleInterface/"
}
}
}
$ composer dump-autoload
作成したクラスを実行します。
<?php
require __DIR__ . '/../vendor/autoload.php';
use SampleInterface\Cat;
use SampleInterface\Dog;
$dog = new Dog();
echo $dog->sleep() . "\n"; // 犬は 12~14 時間寝ます。
$dog = new Cat();
echo $dog->sleep() . "\n"; // 猫は 12~16 時間寝ます。
どちらのクラスもインターフェースで定義したメソッドを実装していますが、具体的な処理はサブクラス側で実装しているので内容は異なります。
複数のインターフェースを実装
抽象クラスは一つのクラスしか継承することが出来ませんでしたが、インターフェースは複数実装することが出来ます。サンプルとして新たにIAnimal2.php
とIAnimal3.php
を作成します。
<?php
namespace SampleInterface;
interface IAnimal2
{
public function eat(); // 動物は食べます
}
<?php
namespace SampleInterface;
interface IAnimal3
{
public function run(); // 動物は走ります
}
これらのインターフェースを実装します。
<?php
namespace SampleInterface\le\SampleInterface;
use SampleInterface\IAnimal;
use SampleInterface\IAnimal2;
use SampleInterface\IAnimal3;
class Cat implements IAnimal, IAnimal2, IAnimal3 // カンマ区切りで複数実装することが出来る
{
public function sleep()
{
return "猫は 12~16 時間寝ます。";
}
public function run()
{
return "猫は素早く走ります。";
}
public function eat()
{
return "猫はよく食べます。";
}
}
Dog.php
にも同様に実装します。
<?php
namespace SampleInterface;
use SampleInterface\IAnimal;
use SampleInterface\IAnimal3;
class Dog implements IAnimal, IAnimal3 // 実装するインターフェースを任意に選択することも出来る
{
public function sleep()
{
return "犬は 12~14 時間寝ます。";
}
public function run()
{
return "犬の走る速度は人間より速いです。";
}
}
このように必要な機能を選択して実装することが出来ます。
インターフェースまとめ
- インターフェースとは、全てのメソッドで具体的な実装がされていない仕様を定義した集まりのこと(どのようなメソッドが必要かだけ定義する)
- 抽象クラスでは具体的な処理内容を記述したメソッドも定義できたが、インターフェースでは抽象メソッドしか定義できない
- インターフェースでは継承ではなく、実装と呼ぶ
- インターフェースの実装には
implements
を使う - 抽象メソッドと同様に、インターフェースに定義したメソッドは実装先で必ず記述する必要がある
- 必ず実装してもらうためのクラスのテンプレートとしてインターフェースを使
- 複数のインタフェースを実装することが出来る