Y a-t-il un moyen de traverser un objet pour obtenir les données d'objet parent?
Avec "objet parent", je ne veux pas dire la classe mère, mais à la lettre d'objet.
Voici un exemple, dans un monde Javascrectty :-): Ce serait génial si je pouvais accéder à toutes les données de parent dans l'objet enfant: P> class B{
//I know this doesn't exists, but it's what I wanted do do
function B(){
$this->parent = $this->parent();
echo $this->parent->test; //it would ouput "hello world"
}
}
6 Réponses :
N °
Vous pouvez accéder aux variables de la superclasse en utilisant: p>
Ce n'était pas la question. Il ne veut pas accéder à la superclasse.
Je pense que cette réponse est bien ("Non."). Sjoerd fournit également une solution alternative.
Passer le parent à l'enfant est la meilleure solution. Bien que ce soit une relation symbiotique quelque peu indésirable. P>
devrait-il b () avoir une connaissance de l'objet c'est un attribut de? Plus que probablement pas. Celles-ci ne sont que lâchées par une composition. P>
Pourquoi B () doit être un attribut de son parent? Avez-vous besoin d'avoir cette implémentation en B () ou de faire partie du parent? P>
Après un mois de JavaScript, où l'objet traversant est normal, je trouve PHP juste trop "statique" dans ce cas. Pensez à un cadre MVC où certaines propriétés sont définies sur le chemin et non par défaut et à la fin de la classe de contrôleur principale appelle une méthode qui déclenche une création d'objet enfant. Si j'utilise la méthode "étendue" par Sjoerd, je ne peux pas alors accéder aux propriétés créées sur le chemin, mais simplement les propriétés définies sur le haut de la classe.
Vous devez donc transmettre un objet qui contient les informations que vous construisez? Peut-être devriez-vous repenser cette conception pour réduire le couplage - un conteneur d'injection de dépendance pourrait-il aider ici?
Je suis sûr que PHP n'a pas quelque chose comme ça. P>
Votre solution de passage de l'objet parent à l'enfant est la meilleure solution, je pense. Vous devriez envisager de définir votre propriété parent uniquement dans le constructeur de l'enfant pour empêcher plusieurs parents d'avoir le même enfant. P>
Il n'y a aucun moyen d'appeler et a automatiquement une référence à $ parent en b. p> Généralement, il y a quatre façons de structurer votre Classes: P> Utilisez une injection de constructeur lorsque l'objet doit avoir un parent lors de sa création. Ceci est une relation a-une em> et crée un couplage très lâche. Il n'y a pas de dépendances codées dans B, de sorte que vous pouvez facilement échanger l'instance parent, par exemple avec une simulacre lorsqu'il est unitest. Utilisation d'une injection de dépendance rendra votre code plus maintenu. P> dans votre usecase, vous passeriez Ceci est également une relation a-une em>, mais couples la classe mère à B. Ce n'est pas non plus existant Instance parent, mais une nouvelle instance. Depuis le libellé, je trouve quelque peu étrange d'avoir un parent créé par l'enfant. Utilisez ceci, lorsque la dépendance est une classe qui n'est pas considérée comme existante existent en dehors de la classe racine, mais fait partie de la chose qu'elle représente. P> pour votre usecase, il n'y a aucun moyen de faire de cette façon, vous créez une relation est-a em>. Toutes les méthodes et propriétés publiques et protégées de la classe mère (mais pas d'une instance spécifique) seront disponibles en B et vous pouvez y accéder via le mot clé code> de l'instance B. P> Pour votre usecase, cette approche ne fonctionne pas, car vous n'avez pas besoin d'une instance de parent du tout, mais B encapsulerait tout de parent lors de sa création p> de toute façon, espère que cela aide. P> p>
$ parent code> à b lors de la création de B: p> $ parent-> enfant = nouveau b (); code> et savoir ce que le parent est lorsque vous utilisez cette approche, sauf si $ parent n'est un singleton. Si tel est le cas, vous pourriez obtenir l'instance Singleton, par ex. Parent :: getinstance () code> Pour réaliser ce que vous voulez, mais notez que les singletons ne sont pas le modèle préféré de tout le monde, par exemple. Difficile à tester. P> global code> Importation de variables globales dans la portée actuelle. En général, Vous devez éviter d'utiliser le mot-clé global dans un contexte OO, mais Utilisez l'une des trois autres méthodes ci-dessus, de préférence le premier. Bien que ce soit une caractéristique linguistique, il est froncé sur - bien qu'il s'agisse de la prochaine chose la plus proche du premier, par exemple p>
C'est tellement étrange
Merci d'avoir gardé cet article à jour, Gordon. Joli.
Peut-être que cela peut être utile dans certains cas: il n'apporte pas l'objet parent à la classement enfant très tôt dans le constructeur, mais une étape plus tard. Il joue avec la possibilité d'intercepter la méthode non existante: ceci produira certaines données code> p> p> p> p>
Vous pouvez créer des collections d'enfants d'objet lorsque vous créez les enfants. Vous le créez au pont le parent de cette façon, ils ne peuvent pas se référencer mutuellement, mais vous pouvez accéder à la fois aux parents et aux enfants, le parent et les enfants des enfants ...
class ChildObject
{
public $name;
}
class ParentObject
{
public $children = array();
public function new_child($text = 'my name is data')
{
$child = new ChildObject; // create a new child
$child->name = $text; // assign the name
$this->children[] = $child; // store it as part of this object
return $child; // return the new instance of Child
}
public function print_everything ()
{
foreach($this->children as $child) {
echo $child->name;
}
}
}
$parent = new ParentObject;
$child1 = $parent->new_child(); // this is a ChildObject not a ParentObject
$child2 = $parent->new_child('i am not data');
echo $child1->name; // 'my name is data'
echo $child2->name; // 'i am not data'
$child1->name = 'something else';
echo $child1->name; // 'something else'
$parent->print_everything(); // 'something else' and 'i am not data'
Ce n'est que deux objets avec des références les unes aux autres. Vous pouvez les appeler parent et enfant.
Pourquoi avez-vous besoin que l'enfant ait une référence à son parent? Y a-t-il quelque chose dans le parent que l'enfant a besoin d'accès aussi? Si vous êtes donc préférable de passer à l'enfant tout ce dont vous pourriez avoir besoin plutôt que d'essayer de l'obtenir du parent.
J'ai dans le parent un "objet de confidentialité", alors quelques variables dont j'ai besoin chez l'enfant et les transmettre tout serait fastidieux ...
$ enfant = nouveau b ($ parent -> Confidentialité); travaillerait? L'instance de B () doit-elle être un attribut de classe de $ parent?
Oui, mais ça ne suffit pas: j'ai besoin de $ enfant = nouveau b ($ parent-> utilisateur, $ parent-> confidentialité, $ parent-> url); Alors pour la commodité, je suis passé à $ enfant = nouveau B ($ parent);
Vous pouvez éviter cette situation si vous suivez les conseils ici: http://misko.heuvery.com/2008/08/01/circulaire-Dependency-in-co NStructeurs-and-Depen Dendy-Injection /
J'ai récemment trébuché dans le même problème. Je ne veux pas que l'enfant "étendre" le parent, car l'enfant n'a rien à voir avec d'autres fonctions déjà définies de son parent. Donc, la seule façon raisonnable pour moi semblait injecter des parents pendant la construction, comme le suggèrent la solution 1 de Gordon. J'aimerais vraiment savoir cependant, s'il y a une langue qui le soutient de manière native. avoir ceci-> parent comme conteneur d'objet parent réel plutôt que la structure de la classe mère