次のプログラムを見てみましょう。
// 書籍
class Book {
private int $price;
public function getPrice() {
return $this->price;
}
}
// 鉛筆
class Pencil {
public int $price;
}
書籍を管理する「Book」と、鉛筆を管理する「Pencil」というクラスを定義しています。どちらも、金額を管理する「$price」というプロパティを定義していますが、一方はprivateで定義して、金額を取得するには「getPrice」というメソッドを通じて取得する必要があり、一方はpublicで定義していて直接取得ができます。
このように、似たようなクラスなのにルールがバラバラだと使いにくくなってしまいます。このような時に使えるのが「インターフェイス」です。
インターフェイスを宣言しよう
次のように書き加えてみましょう。
interface Item {
public function getPrice(): string;
}
...
インターフェイスというのはクラスの宣言と似ていますが、中に記述できるのはpublicメソッドの宣言部分と定数のみを宣言できます。プロパティを宣言したり、privateのメソッドなどを定義することもできません。次のような記述はエラーになります。
interface Item {
private int $price;
private getPrice(): string;
}
では、この宣言したインターフェイスはどのように使うのでしょう。
インターフェイスを実装する implements
クラスを宣言するとき、implementsという記述を使ってインターフェイスを指定することができます。次のように変えてみましょう。
<?php
interface Item {
public function getPrice(): string;
}
// 書籍
class Book implements Item {
private int $price;
public function getPrice(): string {
return $this->price;
}
}
// 鉛筆
class Pencil implements Item {
public int $price;
}
こうして実行すると、次のエラーが発生します。
PHP Fatal error: Class Pencil contains 1 abstract method and must therefore be declared abstract or implement the remaining methods (Item::getPrice)
インターフェイスで「getPrice」メソッドを宣言していると、それを実装したクラスでは必ずそのメソッドを定義しなければなりません。そのため、Pencilクラスを次のようにする必要があります。
<?php
interface Item {
public function getPrice(): string;
}
// 書籍
class Book implements Item {
private int $price;
public function getPrice(): string {
return $this->price;
}
}
// 鉛筆
class Pencil implements Item {
public int $price;
public function getPrice(): string {
return $this->price;
}
}
インターフェイスを利用すると、このようにクラスに対してルールを強いることができます。これによって、クラスを使う側からは「必ずそのメソッドが使える」ということが分かるので、安心して使うことができるようになります。
完成プログラム
<?php
interface Item {
public function getPrice(): string;
}
// 書籍
class Book implements Item {
private int $price;
public function getPrice(): string {
return $this->price;
}
}
// 鉛筆
class Pencil implements Item {
public int $price;
public function getPrice(): string {
return $this->price;
}
}