Si j'ai plusieurs classes avec des fonctions dont j'ai besoin mais que je souhaite stocker séparément pour l'organisation, puis-je étendre une classe pour avoir les deux?
c'est à dire class a extends b extends c
edit: Je sais comment étendre les classes une à la fois, mais je recherche une méthode pour étendre instantanément une classe en utilisant plusieurs classes de base - AFAIK vous ne pouvez pas faire cela en PHP mais il devrait y avoir des moyens de contourner cela sans recourir à class c extends b
,class b extends a
Réponses:
Répondre à votre modification:
Si vous voulez vraiment simuler l'héritage multiple, vous pouvez utiliser la fonction magique __call ().
C'est moche bien que cela fonctionne du point de vue de l'utilisateur de classe A:
Imprime "abcdef"
la source
Vous ne pouvez pas avoir une classe qui étend deux classes de base. Vous ne pourriez pas avoir.
Vous pourriez cependant avoir une hiérarchie comme suit ...
etc.
la source
Vous pouvez utiliser des traits qui, espérons-le, seront disponibles à partir de PHP 5.4.
Traits est un mécanisme de réutilisation de code dans des langages d'héritage uniques tels que PHP. Un trait est destiné à réduire certaines limitations de l'héritage unique en permettant à un développeur de réutiliser librement des ensembles de méthodes dans plusieurs classes indépendantes vivant dans des hiérarchies de classes différentes. La sémantique de la combinaison de Traits et de classes est définie de manière à réduire la complexité et à éviter les problèmes typiques associés à l'héritage multiple et aux Mixins.
Ils sont reconnus pour leur potentiel à soutenir une meilleure composition et réutilisation, d'où leur intégration dans les nouvelles versions de langages tels que Perl 6, Squeak, Scala, Slate et Fortress. Les traits ont également été portés vers Java et C #.
Plus d'informations: https://wiki.php.net/rfc/traits
la source
Les classes ne sont pas destinées à être simplement des collections de méthodes. Une classe est censée représenter un concept abstrait, avec à la fois un état (champs) et un comportement (méthodes) qui change l'état. Utiliser l'héritage juste pour obtenir un comportement souhaité ressemble à une mauvaise conception OO, et c'est exactement la raison pour laquelle de nombreux langages interdisent l'héritage multiple: afin d'éviter "l'héritage spaghetti", c'est-à-dire étendre 3 classes car chacune a une méthode dont vous avez besoin, et se retrouver avec une classe qui hérite de 100 méthodes et 20 champs, mais n'en utilise que 5.
la source
Il est prévu d'ajouter bientôt des mix-ins, je crois.
Mais jusque-là, allez avec la réponse acceptée. Vous pouvez faire un résumé de cela pour créer une classe "extensible":
Notez que dans ce modèle, "OtherClass" apprend à "connaître" $ foo. OtherClass doit avoir une fonction publique appelée "setExtendee" pour configurer cette relation. Ensuite, si ses méthodes sont appelées à partir de $ foo, il peut accéder à $ foo en interne. Cependant, il n'aura pas accès à des méthodes / variables privées / protégées comme le ferait une vraie classe étendue.
la source
Utilisez les traits comme classes de base. Ensuite, utilisez-les dans une classe parent. Prolongez-le.
Voir maintenant femme d'affaires logiquement héritée des affaires et humaine à la fois;
la source
BusinessWoman
lieu deBusinessPerson
? Ensuite, vous pouvez avoir un héritage multiple réel.la source
La réponse actuellement acceptée par @Franck fonctionnera mais ce n'est pas en fait un héritage multiple mais une instance enfant de classe définie hors de portée, il y a aussi le
__call()
raccourci - envisagez d'utiliser$this->childInstance->method(args)
n'importe où vous avez besoin de la méthode de classe ExternalClass dans la classe "étendue".Réponse exacte
Non, vous ne pouvez pas, respectivement, pas vraiment, comme le
extends
dit le manuel du mot - clé :Vraie réponse
Cependant, comme @adam l'a suggéré correctement, cela ne vous interdit PAS d'utiliser l'héritage hiérarchique multiple.
Vous POUVEZ étendre une classe, avec une autre et une autre avec une autre et ainsi de suite ...
Un exemple assez simple à ce sujet serait:
Note importante
Comme vous l'avez peut-être remarqué, vous ne pouvez faire plusieurs intégrations (2+) par hiérarchie que si vous avez le contrôle sur toutes les classes incluses dans le processus - cela signifie que vous ne pouvez pas appliquer cette solution, par exemple avec des classes intégrées ou avec des classes que vous ne peut tout simplement pas modifier - si vous voulez faire cela, vous vous retrouvez avec la solution @Franck - les instances enfants.
... Et enfin exemple avec une sortie:
Quelles sorties
la source
J'ai lu plusieurs articles décourageant l'héritage dans les projets (par opposition aux bibliothèques / frameworks), et encourageant à programmer des interfaces agaisnt, non contre les implémentations.
Ils préconisent également l'OO par composition: si vous avez besoin des fonctions des classes a et b, faites en sorte que c ait des membres / champs de ce type:
la source
L'héritage multiple semble fonctionner au niveau de l'interface. J'ai fait un test sur php 5.6.1.
Voici un code fonctionnel:
Je ne pensais pas que c'était possible, mais je suis tombé sur le code source de SwiftMailer, dans la classe Swift_Transport_IoBuffer, qui a la définition suivante:
Je n'ai pas encore joué avec, mais j'ai pensé que cela pourrait être intéressant à partager.
la source
Je viens de résoudre mon problème "d'héritage multiple" avec:
De cette façon, j'ai le pouvoir de manipuler une session à l'intérieur d'une SessionResponse qui étend MyServiceResponsetype tout en étant capable de gérer Session par lui-même.
la source
Si vous souhaitez vérifier si une fonction est publique, consultez cette rubrique: https://stackoverflow.com/a/4160928/2226755
Et utilisez la méthode call_user_func_array (...) pour plusieurs arguments ou pas.
Comme ça :
la source
Vous pouvez le faire en utilisant Traits en PHP qui a annoncé à partir de PHP 5.4
Voici un petit tutoriel pour vous, http://culttt.com/2014/06/25/php-traits/
la source
PHP ne prend pas encore en charge l'héritage de classes multiples, il prend cependant en charge l'héritage d'interfaces multiples.
Voir http://www.hudzilla.org/php/6_17_0.php pour quelques exemples.
la source
PHP n'autorise pas l'héritage multiple, mais vous pouvez le faire avec l'implémentation de plusieurs interfaces. Si l'implémentation est "lourde", fournissez une implémentation squelettique pour chaque interface dans une classe distincte. Ensuite, vous pouvez déléguer toutes les classes d'interface à ces implémentations squelettiques via le confinement d'objets .
la source
Ne sachant pas exactement ce que vous essayez de réaliser, je suggérerais d'examiner la possibilité de reconcevoir votre application pour utiliser la composition plutôt que l'héritage dans ce cas.
la source
Une bonne idée est toujours de créer une classe parent, avec des fonctions ... c'est-à-dire d'ajouter toutes ces fonctionnalités au parent.
Et "déplacez" toutes les classes qui l'utilisent de manière hiérarchique vers le bas. J'ai besoin - des fonctions de réécriture, qui sont spécifiques.
la source
L'un des problèmes de PHP en tant que langage de programmation est le fait que vous ne pouvez avoir qu'un seul héritage. Cela signifie qu'une classe ne peut hériter que d'une autre classe.
Cependant, la plupart du temps, il serait avantageux d'hériter de plusieurs classes. Par exemple, il peut être souhaitable d'hériter des méthodes de quelques classes différentes afin d'éviter la duplication de code.
Ce problème peut conduire à une classe qui a une longue histoire familiale d'héritage qui n'a souvent pas de sens.
En PHP 5.4, une nouvelle fonctionnalité du langage a été ajoutée, appelée Traits. Un Trait est un peu comme un Mixin en ce qu'il vous permet de mélanger des classes de Trait dans une classe existante. Cela signifie que vous pouvez réduire la duplication de code et bénéficier des avantages tout en évitant les problèmes d'héritage multiple.
Traits
la source
Ce n'est pas une vraie réponse, nous avons une classe en double
... mais ça marche :)
la classe copy_B est une copie de toute la classe B
maintenant
la source
la classe A étend B {}
la classe B étend C {}
Alors A a étendu B et C
la source
B
. Ce que nous voulons la plupart du temps, c'est d'avoir deux classes non liéesB
etC
(probablement de bibliothèques différentes) et d'être héritées simultanément parA
, de sorte qu'ellesA
contiennent tout des deuxB
etC
, maisB
ne contiennent rien deC
et vice versa.