Une classe peut-elle étendre à la fois une classe et implémenter une interface

100

Une classe peut-elle étendre à la fois une interface et une autre classe en PHP?
En gros, je veux faire ceci:

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

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

Comment ferait-on cela, en faisant simplement:

class database implements databaseInterface extends mysqli{ 

entraîne une erreur fatale:

Erreur d'analyse: erreur de syntaxe, T_EXTENDS inattendu, attente de '{' dans * fichier * sur la ligne * ligne *
Pim Jager
la source
18
En quoi est-ce trop localisé?! "Il est peu probable que cette question aide les futurs visiteurs". Pourtant, la meilleure réponse a 33 votes positifs et la question 4 étoiles!
duality_

Réponses:

177

Essayez-le dans l'autre sens:

class database extends mysqli implements databaseInterface { ...}

Cela devrait fonctionner.

Simon Lehmann
la source
Ahh, merci beaucoup. Pourquoi exactement devraient-ils être l'inverse?
Pim Jager
14
Puisque vous ne pouvez hériter que d'une classe et que vous pouvez implémenter n'importe quel nombre d'interfaces, c'était probablement une chose de sucre de syntaxe. Souvenez-vous également que si votre sous-classe implémente des interfaces, cela apparaîtra également dans la liste des méthodes implémentées. Il est donc logique de les mettre dans cet ordre.
Tiré
Est-ce une mauvaise pratique?
Mohammed Shamshid
21

Oui il peut. Il vous suffit de conserver le bon ordre.

class database extends mysqli implements databaseInterface { ... }

De plus, une classe peut implémenter plus d'une interface. Séparez-les simplement par des virgules.

Cependant, je me sens obligé de vous avertir que l' extension de la classe mysqli est une très mauvaise idée . L'héritage en soi est probablement le concept le plus surfait et le plus mal utilisé dans la programmation orientée objet.

Au lieu de cela, je conseillerais de faire des choses liées à la base de données à la manière mysqli (ou PDO).

De plus, une chose mineure, mais les conventions de dénomination comptent. Votre classe databasesemble alors plus générale mysqli, donc elle suggère que ce dernier hérite de databaseet non pas de la manière autour.

Michał Rudnicki
la source
1
Pourquoi étendre la classe mysqli est-il une mauvaise idée?
Pim Jager
11
Premièrement, parce que ce n'est pas le vôtre. Lorsque les gars de mysqli décident de changer quelque chose, le comportement de la sous-classe changera également. Deuxièmement, l'héritage est utilisé pour SPÉCIALISER, et non étendre avec des fonctionnalités supplémentaires. C'est la chose la plus mal comprise de la POO. En règle générale, j'ai tendance à étendre uniquement les classes abstraites.
Michał Rudnicki
Michal - En quoi un changement de mysqli serait-il différent pour un développeur qui utilise une approche polymorphe par rapport à une approche agrégée / composée? Vous devrez toujours mettre à jour votre code pour gérer les modifications.
Peter Bailey
2
Je connais le modèle d'adaptateur. Je dis simplement que si un nom de méthode change ou est obsolète, vous devrez toujours changer le code dans les deux scénarios. Bien que je sois d'accord pour dire qu'une approche non polymorphe est meilleure dans ce scénario, je n'achète pas l'idée qu'un adaptateur serait «immunisé» au changement.
Peter Bailey
2
Vous n'aurez qu'à changer le code de l'adaptateur, pas tous les endroits utilisant ce code. Avec la composition, vous pouvez fournir une couche de compatibilité quoi qu'il arrive, alors qu'avec l'héritage, vous pouvez l'appeler au mieux un hack. Et, je reste corrigé, l'adaptateur offrirait une meilleure immunité au changement.
Michał Rudnicki
6

oui, en fait, si vous souhaitez implémenter plusieurs interfaces, vous pouvez faire comme ceci:

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

}
pointeur nul
la source