Perché avresti bisogno di un'interfaccia, se ci sono già classi astratte?
Per impedire l'ereditarietà multipla (può causare più problemi noti).
Uno di questi problemi:
Il "problema del diamante" (a volte indicato come il "diamante mortale della morte") è un'ambiguità che sorge quando due classi B e C ereditano da A e la classe D eredita sia da B che da C. Se esiste un metodo in A che B e C hanno sovrascritto e D non ha la precedenza, quindi quale versione del metodo eredita D: quella di B o quella di C?
Fonte: https://en.wikipedia.org/wiki/Multiple_inheritance#The_diamond_problem
Perché / quando utilizzare un'interfaccia?
Un esempio ... Tutte le auto del mondo hanno la stessa interfaccia (metodi) ... AccelerationPedalIsOnTheRight()
,BrakePedalISOnTheLeft()
. Immagina che ogni marchio automobilistico avrebbe questi "metodi" diversi da un altro marchio. La BMW avrebbe i freni sul lato destro e la Honda avrebbe i freni sul lato sinistro della ruota. Le persone dovrebbero imparare come funzionano questi "metodi" ogni volta che comprano una marca diversa di auto. Ecco perché è una buona idea avere la stessa interfaccia in più "luoghi".
Cosa fa un'interfaccia per te (perché qualcuno dovrebbe persino usarne una)? Un'interfaccia ti impedisce di fare "errori" (ti assicura che tutte le classi che implementano un'interfaccia specifica, avranno tutti i metodi che sono nell'interfaccia).
// 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).
}
}
In questo modo, il Create()
metodo verrà sempre utilizzato allo stesso modo. Non importa se stiamo usando la MySqlPerson
classe o ilMongoPerson
classe. Il modo in cui stiamo usando un metodo rimane lo stesso (l'interfaccia rimane la stessa).
Ad esempio, verrà utilizzato in questo modo (ovunque nel nostro codice):
new MySqlPerson()->Create($personObject);
new MongoPerson()->Create($personObject);
In questo modo, qualcosa del genere non può accadere:
new MySqlPerson()->Create($personObject)
new MongoPerson()->Create($personsName, $personsAge);
È molto più facile ricordare un'interfaccia e usare la stessa ovunque, piuttosto che più diverse.
In questo modo, l'interno del Create()
metodo può essere diverso per le diverse classi, senza influire sul codice "esterno", che chiama questo metodo. Tutto il codice esterno che deve sapere è che il metodo Create()
ha 1 parametro ( $personObject
), perché è così che il codice esterno utilizzerà / chiamerà il metodo. Al codice esterno non importa cosa sta succedendo all'interno del metodo; deve solo sapere come usarlo / chiamarlo.
Puoi farlo anche senza un'interfaccia, ma se usi un'interfaccia, è "più sicuro" (perché ti impedisce di fare errori). L'interfaccia ti assicura che il metodo Create()
avrà la stessa firma (stessi tipi e lo stesso numero di parametri) in tutte le classi che implementano l'interfaccia. In questo modo puoi essere sicuro che QUALSIASI classe che implementa l' IPersonService
interfaccia, avrà il metodo Create()
(in questo esempio) e avrà bisogno solo di 1 parametro ( $personObject
) per essere chiamato / usato.
Una classe che implementa un'interfaccia deve implementare tutti i metodi, che l'interfaccia ha / ha.
Spero di non ripetermi troppo.