Una classe può estendere sia una classe che implementare un'interfaccia


100

Una classe può estendere sia un'interfaccia che un'altra classe in PHP?
Fondamentalmente voglio fare questo:

interface databaseInterface{
 public function query($q);
 public function escape($s);
 //more methods
}

class database{ //extends both mysqli and implements databaseInterface
 //etc.
}

Come si fa, semplicemente facendo:

class database implements databaseInterface extends mysqli{ 

si traduce in un errore fatale:

Errore di analisi: errore di sintassi, T_EXTENDS imprevisto, in attesa di "{" in * file * sulla riga * riga *

18
Come è troppo localizzato ?! "È improbabile che questa domanda possa aiutare i futuri visitatori". Eppure la risposta migliore ha 33 voti positivi e la domanda 4 stelle!
dualità_

Risposte:


177

Provalo al contrario:

class database extends mysqli implements databaseInterface { ...}

Questo dovrebbe funzionare.


Ahh, grazie mille. Perché esattamente dovrebbero essere il contrario?
Pim Jager

14
Dal momento che puoi ereditare solo una classe e puoi implementare un numero qualsiasi di interfacce, probabilmente era una questione di sintassi. Inoltre, ricorda, se la tua sottoclasse implementa delle interfacce, anche queste verranno visualizzate nell'elenco dei metodi implementati. Quindi metterli in quell'ordine ha un certo senso.
Drew

È una cattiva pratica?
Mohammed Shamshid,

21

Sì, può. Hai solo bisogno di mantenere l'ordine corretto.

class database extends mysqli implements databaseInterface { ... }

Inoltre, una classe può implementare più di un'interfaccia. Separali con virgole.

Tuttavia, mi sento in dovere di avvertirti che estendere la classe mysqli è una pessima idea . L'ereditarietà di per sé è probabilmente il concetto più sopravvalutato e abusato nella programmazione orientata agli oggetti.

Invece consiglierei di fare cose relative a db nel modo mysqli (o nel modo PDO).

Inoltre, una cosa minore, ma le convenzioni di denominazione contano. La tua classe databasesembra quindi più generale mysqli, quindi suggerisce che quest'ultima eredita da databasee non il modo per aggirarla.


1
Perché estendere la classe mysqli è una cattiva idea?
Pim Jager

11
Primo, perché non è tuo. Quando i ragazzi di mysqli decidono di cambiare qualcosa, cambierà anche il comportamento di una sottoclasse. In secondo luogo, l'ereditarietà viene utilizzata per SPECIALIZZARE, non ESTENDERE con funzionalità aggiuntive. Questa è la cosa più fraintesa in OOP. Come regola generale, tendo ad estendere solo le classi astratte.
Michał Rudnicki

Michal - in che modo una modifica a mysqli sarebbe diversa per uno sviluppatore che utilizza un approccio polimorfico rispetto a uno aggregato / composto? Dovresti comunque aggiornare il tuo codice per gestire le modifiche.
Peter Bailey

2
Ho familiarità con il modello dell'adattatore. Sto solo dicendo che se il nome di un metodo cambia o è deprecato, sarà comunque necessario modificare il codice in entrambi gli scenari. Sebbene sia d'accordo che un approccio non polimorfico sia migliore in questo scenario, non credo che un adattatore sarebbe "immune" al cambiamento.
Peter Bailey

2
Dovrai solo cambiare il codice dell'adattatore, non tutti i posti che utilizzano quel codice. Con la composizione puoi fornire un livello di compatibilità qualunque cosa accada, mentre con l'ereditarietà puoi chiamarlo nel migliore dei casi un hack. E, ho corretto, l'adattatore fornirebbe una migliore immunità al cambiamento.
Michał Rudnicki

6

si, infatti se vuoi implementare più interfacce puoi fare così:

public class MyClass extends BaseClass implements myInterface1, myInterface2, myInterface3{ 

}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.