# ch05 — インターフェイス (interface / implements)

Source: https://php-school.pages.dev/topics/class-advanced/ch05-interface/
Site: AIと学ぶPHPの学校 (https://php-school.pages.dev)
Lesson: クラスの応用
Level: L3

Reference (official): https://www.php.net/manual/ja/language.oop5.inheritance.php

## 本文

# ch05 — インターフェイス (interface / implements)

## 概要

インターフェース (interface) は **「このメソッドを実装してほしい」という契約だけを並べたもの** で、`interface Printable { public function print(): void; }` のように書く。中身は持たず、メソッドの **名前と引数と戻り値型** だけを宣言する場所になる。クラス側で `class Book implements Printable` と書いて、そのクラスが「`Printable` の契約を守る」と宣言し、契約に書かれたメソッドをすべて実装することで初めてコンパイルが通る。

抽象クラスとの最大の違いは **多重実装ができる** こと。PHP では `extends` で親クラスは 1 つしか持てないが、`implements` は `implements A, B, C` のように複数並べられる。「印刷できる」「シリアライズできる」「並び替えできる」のような複数の能力を 1 つのクラスに持たせたいとき、それぞれをインターフェースとして切っておけば自由に組み合わせられる。

設計上の意義は **「実装ではなく契約に依存する」** こと。ある関数が「`Printable` を受け取る」と書かれていれば、`Book` でも `Magazine` でも `Receipt` でも、`Printable` を実装していれば何でも渡せる。後から新しいクラスを追加するときも、既存のコードを変更せずに `implements Printable` を付けるだけで組み込める。これがフレームワークの拡張点が決まる仕組みの根幹になる。

## 学習目標

- `interface` は「メソッドの一覧 (契約)」だけを定義する
- `implements` で「この契約を守る」と宣言できる
- 継承 (`extends`) と違って **複数のインターフェイスを実装** できる

## 所要時間

スライド 5 分 + ドリル 1 問 = **12 分**

## ドリル

| no | 内容 |
|---|---|
| 01 | `interface Printable` を `Book` で `implements` し、`print()` を実装する |

## 採点

```bash
php scripts/grade.php topics/class-advanced/ch05-interface/drill/01-printable/
```

## 関連チャプター

- [`ch04-abstract`](../ch04-abstract/) — 共通実装を持つ抽象クラス
- [`ch02-override`](../ch02-override/) — オーバーライドとの関係
- [`ch01-inheritance`](../ch01-inheritance/) — 継承

## スライド

---
marp: true
theme: dojo
paginate: true
size: 16:9
---

<!--
LLM_CONTEXT:
  Lesson 9 / Chapter 5
  目的: interface / implements で「メソッドの契約」を定義し、複数の契約を実装させる
  扱わない: static (ch06) / const (ch07) / final (ch08) / 抽象クラスとの使い分け詳細
  読み上げ時間目安: 4 分半〜5 分
-->

# インターフェイス (interface)

Lesson 9 / Chapter 5

---

## 「中身」を持たない「契約」だけのクラス

```php
<?php
interface Printable {
    public function output(): void;
}
```

- `interface` は **メソッドの一覧** だけ
- 中身 `{ ... }` も、プロパティも書かない
- 「このメソッドを必ず持っている」という **約束** を定義する

---

## `implements` で契約を守ると宣言

```php
<?php
class Book implements Printable {
    public string $title;

    public function output(): void {
        echo "本のタイトル: {$this->title}\n";
    }
}
```

- `implements インターフェイス名` で「この契約を守る」と宣言
- 契約 (`output`) を実装しないと **Fatal error**
- 子は親契約を満たす義務がある

---

## 使い方は普通のメソッド呼び出し

```php
<?php
$b = new Book();
$b->title = "PHP 入門";
$b->output();
```

実行結果:

```
本のタイトル: PHP 入門
```

- 使う側は「インターフェイスを実装してる」ことしか知らなくて良い
- 中身がどう書かれているかは気にしない

---

## abstract class とどう違う?

|  | abstract class | interface |
|---|---|---|
| インスタンス化 | できない | できない |
| プロパティ | 持てる | 持てない (定数は OK) |
| メソッドの中身 | 書ける | 書けない |
| 継承・実装の数 | 1 つだけ | **複数 OK** |

---

## 1 つのクラスで複数のインターフェイスを実装

```php
<?php
interface Printable { public function output(): void; }
interface Sellable { public function price(): int; }

class Book implements Printable, Sellable {
    public string $title;
    public function output(): void { echo "{$this->title}\n"; }
    public function price(): int { return 1500; }
}
```

- カンマで並べる
- 「印刷可能」かつ「販売可能」の両方の契約を満たす

---

## このチャプターでできるようになること

✅ `interface` でメソッドの契約を定義できる
✅ `implements` で契約を守ると宣言できる
✅ 1 クラスで複数のインターフェイスを実装できる
✅ abstract class との使い分けを言える

→ ドリルへ
