抽象クラスがすでにあるのに、なぜインターフェースが必要なのでしょうか?
多重継承を防ぐため(複数の既知の問題を引き起こす可能性があります)。
そのような問題の1つ:
「ダイヤモンドの問題」(「致命的な死のダイヤモンド」と呼ばれることもあります)は、2つのクラスBとCがAから継承し、クラスDがBとCの両方から継承する場合に発生する曖昧さです。Aにメソッドがある場合、 BとCはオーバーライドされ、Dはオーバーライドしません。Dが継承するメソッドのバージョンは、Bのバージョンですか、それともCのバージョンですか。
出典:https : //en.wikipedia.org/wiki/Multiple_inheritance#The_diamond_problem
なぜ/いつインターフェースを使用するのですか?
例...世界のすべての車は同じインターフェース(メソッド)を持っています... AccelerationPedalIsOnTheRight()
、BrakePedalISOnTheLeft()
。各自動車ブランドがこれらの「方法」を他のブランドとは異なるものにすると想像してください。BMWは右側にブレーキがあり、ホンダはホイールの左側にブレーキがあります。人々は、異なるブランドの車を購入するたびに、これらの「方法」がどのように機能するかを学ぶ必要があります。そのため、同じインターフェースを複数の「場所」に配置することをお勧めします。
インターフェイスはあなたのために何をしますか(なぜ誰かがそれを使うのですか?)インターフェースは、「ミス」を防ぐことができます(特定のインターフェースを実装するすべてのクラスが、すべてインターフェースにあるメソッドを持つことを保証します)。
// Methods inside this interface must be implemented in all classes which implement this interface.
interface IPersonService
{
public function Create($personObject);
}
class MySqlPerson implements IPersonService
{
public function Create($personObject)
{
// Create a new person in MySql database.
}
}
class MongoPerson implements IPersonService
{
public function Create($personObject)
{
// Mongo database creates a new person differently then MySQL does. But the code outside of this method doesn't care how a person will be added to the database, all it has to know is that the method Create() has 1 parameter (the person object).
}
}
このように、Create()
メソッドは常に同じ方法で使用されます。MySqlPerson
クラスを使用するか、MongoPerson
クラスを使用するかは関係ありません。メソッドの使用方法は変わりません(インターフェースは変わりません)。
たとえば、次のように使用されます(コードのすべての場所)。
new MySqlPerson()->Create($personObject);
new MongoPerson()->Create($personObject);
このように、このようなことは起こりえません:
new MySqlPerson()->Create($personObject)
new MongoPerson()->Create($personsName, $personsAge);
複数の異なるインターフェースよりも、1つのインターフェースを覚えてどこでも同じインターフェースを使用する方がはるかに簡単です。
このように、Create()
メソッドの内部は、このメソッドを呼び出す「外部」コードに影響を与えることなく、クラスごとに異なる場合があります。外部コードが知っている必要があるのは、メソッドCreate()
が1つのパラメーター($personObject
)を持っていることだけです。これは、外部コードがメソッドを使用/呼び出す方法だからです。外部コードは、メソッド内で何が起こっているかを気にしません。それを使用/呼び出す方法を知っていればよいだけです。
インターフェースがなくてもこれを行うことができますが、インターフェースを使用する場合は「安全」です(間違いを防ぐため)。インターフェイスは、メソッドCreate()
がインターフェイスを実装するすべてのクラスで同じシグネチャ(同じ型と同じ数のパラメーター)を持つことを保証します。このようにして、IPersonService
インターフェースを実装するすべてのクラスが確実にメソッドを持ちCreate()
(この例では)、$personObject
呼び出し/使用するために必要なパラメーター()は1つだけです。
インターフェースを実装するクラスは、インターフェースが行う/持つすべてのメソッドを実装する必要があります。
何度も繰り返さなかったといいのですが。