PHPでインターフェイスと抽象クラスの違いについて

インターフェイスと抽象クラスについて教えていただいたので、メモ

 

インターフェイス

・複数の異なるクラスに共通の機能を実装するための実態の定義

インターフェイスを実装したメソッドはインターフェイス上で定義されている

 メソッドを実装しなければならない

・メソッドの内容は定義できない

・複数のインターフェイスをクラスへ実装することができる

 

【抽象クラス(abstract)】

・共通の機能を抽象的に定義し、子クラスで特有の機能を実装する

・抽象クラスで定義されたabstractメソッドは子クラスで実装しなければならない

abstractをつけないで実装込みのメソッドを定義することができる

・抽象クラスはインスタンスすることが出来ず、継承した子クラスをインスタンスする

 必要がある

 

これだとインターフェイス要らないんじゃないかと思った。しかし

・車抽象クラス

<?php

abstract class Car {
//アクセルを踏む
abstract public function accelerator();

//ブレーキを踏む
abstract public function brake();

//ハンドルを左に切る
abstract public function turn_left();

//ハンドルを右に切る
abstract public function turn_right();

//ギアを上げる
abstract public function gear_up();

//ギアを下げる
abstract public function gear_down();
}

こんな感じのcarクラスがあったとする

 

マニュアル車の場合はこれで問題ないかもしれないけれど、
オートマ車の場合にギアの操作がいらないじゃないかと

AT車クラス

class AtCar extends Car {
//アクセルを踏む
public function accelerator() {
// TODO: Implement accelerator() method.
}

//ブレーキを踏む
public function brake() {
// TODO: Implement brake() method.
}

//ハンドルを左に切る
public function turn_left() {
// TODO: Implement turn_left() method.
}

//ハンドルを右に切る
public function turn_right() {
// TODO: Implement turn_right() method.
}

//ギアを上げる
public function gear_up() {
// TODO: Implement gear_up() method.
}

//ギアを下げる
public function gear_down() {
// TODO: Implement gear_down() method.
}
}

こんな感じで実装しなければならない

$AtCar = new AtCar();
//AT車なのでギア操作がないけど呼べちゃう
$AtCar->gear_up();

の様な矛盾が起こる、バグの元、危ない

そこでインターフェイスを使ってみる

 

・車部品インターフェイス

//速度操作インターフェイス
interface speed {
//アクセルを踏む
public function accelerator();

//ブレーキを踏む
public function brake();
}

//進行方向操作インターフェイス
interface direction {
//ハンドルを左に切る
public function turn_left();

//ハンドルを右に切る
public function turn_right();
}

//ギア操作インターフェイス
interface gear {
//ギアを上げる
public function gear_up();

//ギアを下げる
public function gear_down();
}

このインターフェイスを元にAT車クラスを作成

AT車クラス

class AtCar implements speed, direction {

//アクセルを踏む
public function accelerator() {
// TODO: Implement accelerator() method.
}

//ブレーキを踏む
public function brake() {
// TODO: Implement brake() method.
}

//ハンドルを左に切る
public function turn_left() {
// TODO: Implement turn_left() method.
}

//ハンドルを右に切る
public function turn_right() {
// TODO: Implement turn_right() method.
}
}

ギア操作メソッドなしでOK
MT車クラスを作成する時はgearインターフェイスをimplementsすればOK

なるほどと思った。