Dans chaque exemple que j'ai vu, les classes étendues implémentent les interfaces de leurs parents. Pour référence, l'exemple suivant:
interface MyInterface{
public function foo();
public function bar();
}
abstract class MyAbstract implements MyInterface{
public function foo(){ /* stuff */ }
public function bar(){ /* stuff */ }
}
// what i usually see
class MyClass extends MyAbstract implements MyInterface{}
// what i'm curious about
class MyOtherClass extends MyAbstract{}
Ne pas implémenter une interface dans un enfant, qui est implémentée par un parent, est-il considéré comme une mauvaise pratique ou quelque chose du genre? Y a-t-il des inconvénients techniques à omettre la mise en œuvre chez l'enfant?
Je considérerais que vous êtes sur le bon chemin. Il n'est pas nécessaire de déclarer que vous implémentez l'interface, lors de l'extension d'une classe qui la contient déjà implements
. Pour moi, il ne s'agit que d'un autre code à conserver si des modifications sont nécessaires. Alors oui, vous avez raison!
Le fait de ne pas implémenter une interface Chez un enfant, qui est implémentée par un parent , Est-il considéré comme une mauvaise pratique ou Quelque chose? Existe-t-il des inconvénients techniques À omettre la mise en œuvre de Chez l'enfant?
Je ne peux tout simplement pas répondre à votre question mieux que ce type a:
De par leur nature, même si parfois Elles peuvent sembler assez similaires, les classes abstraites Et les interfaces de classe servent des objectifs Très distincts.
L'interface d'une classe est conçue comme un outil Pour "l'utilisateur" de cette classe. Une interface Est une présentation publique pour La classe, et elle devrait indiquer à Toute personne qui envisage de l’utiliser, quelles méthodes et constantes Sont disponibles et accessible de l'extérieur. Ainsi, Comme son nom l'indique, il se trouve toujours Entre l'utilisateur et la classe Qui l'implémente.
D'autre part, une classe abstraite Est un outil destiné à aider le "réalisateur" Des classes qui L'étendent. Il s’agit d’une infrastructure Qui peut imposer des restrictions et des Directives sur la forme que devraient prendre les classes Concrètes. Du point de vue de la conception de classe , Les classes abstraites Sont plus importantes sur le plan architectural Que les interfaces. Dans ce cas, le réalisateur Se situe entre la classe abstraite Et la classe concrète, en construisant Au-dessus de la première.
C'est donc à vous de décider en fonction de qui va utiliser (instancier) vos cours et qui va les écrire. Si vous êtes le seul utilisateur et rédacteur de vos cours, alors peut-être que vous n’avez peut-être pas besoin des deux. Toutefois, si vous souhaitez donner à chacun un plan détaillé pour les rédacteurs de classe et les utilisateurs de classe, vous devez envisager l’utilisation de l’abrégé et de la mise en œuvre.
Bien, j’étais confus aussi, mais je pense que vous devriez utiliser le dernier, vous avez raison, si vous implémentez l’interface dans la classe abstraite, il n’est pas nécessaire d’écrire l’interface, vous pouvez écrire la méthode dans interface tout en abstraite en tant que méthode abstraite, car vous allez étendre la classe abstraite de quelque manière que ce soit, et vous devrez utiliser la classe abstraite comme un type param lorsque vous utilisez la classe ailleurs, ce n'est pas une bonne chose, je pense qu'une classe abstraite ne devrait pas être utilisé en tant que type param, alors qu'une interface devrait l'être.
Ne pas implémenter une interface dans un enfant, qui est implémentée par un parent, est-il considéré comme une mauvaise pratique ou quelque chose du genre?
L'enfant implémente toujours l'interface, il ne peut pas y aller avec ça.
Je n'ai aucune idée si c'est une mauvaise pratique ou quelque chose. Je dirais que c'est une fonctionnalité linguistique.
Y a-t-il des inconvénients techniques à omettre la mise en œuvre chez l'enfant?
Vous ne pouvez pas tester le reflet de la classe abstraite pour avoir l'interface par exemple.
Cependant, les classes abstraites sont déjà une interface, donc techniquement, elles n'ont pas vraiment besoin de l'interface, mais vous pouvez le faire pour que les choses restent fluides au sein de l'héritage.
Peut-être un peu tard à la table, mais je vois que les commentaires ci-dessus ne clarifient pas le principal malentendu à la base de la question du PO.
Les questions sous-jacentes sont donc les suivantes:
Mais avant quelques précisions, pourquoi utiliser l’une ou l’autre des méthodes ci-dessus:
Une classe abstraite, à son tour, est utilisée pour fournir à la classe concrète créée plus tard le schéma directeur de méthodes et de structures de données via:
Une interface est utilisée pour fournir une classe concrète avec un plan de méthodes via
Voici un exemple de résumé et de classes concrètes.
abstract class MyAbstractClass {
public function foo() {
// Base implementation of the method here.
}
public function bar() {
// Base implementation of the method here.
}
// Effectively similar to baz() declaration within some interface:
public abstract function baz($value);
}
class MyConcreteClass extends MyAbstractClass {
// foo() and bar() are inherited here from MyAbstractClass.
// baz() must be implemented or declared abstract again.
public function baz($value) {
// implementation.
}
}
Alors les questions viennent:
Les réponses:
Etant donné que PHP n'autorise qu'un seul héritage pour chaque sous-classe (vous ne pouvez pas écrire class MyConcreteClass extends MyAbstractClass, MyAnotherClass {}
), lorsque nous devons étendre la fonctionnalité de classe concrète au-delà de la classe Abstract déjà utilisée, nous devons déclarer cette fonctionnalité supplémentaire via une seule. ou plusieurs interfaces.
Comme ça:
class MyConcreteClass
extends MyAbstractClass
implements MyInterface, MyAnotherInterface {
// Methods and data implementations go here.
}
Comme résultat de la réponse 1, une interface préférable de ne pas le faire duplique une déclaration de méthodes d'une classe abstraite (ce qui est fondamentalement inutile). Une ou plusieurs interfaces doivent décrire les méthodes qui peuvent aider à améliorer la fonctionnalité concrète (ou une autre classe abstraite, pourquoi pas) pour permettre au programmeur de les utiliser avec le contrat ferme pour chaque objet construit au-dessus de ces classes et interfaces.
Enfin, répondre à la question du PO sur l’utilisation d’une interface pour une classe abstraite ou pour la classe concrète est: