Comportement étrange lors de la substitution des méthodes privées
Considérer le morceau de code suivant:
class foo {
private function m() {
echo 'foo->m() ';
}
public function call() {
$this->m();
}
}
class bar extends foo {
private function m() {
echo 'bar->m() ';
}
public function callbar() {
$this->m();
}
}
$bar = new bar;
$bar->call();
$bar->callbar();
Maintenant, l'évolution de la visibilité de l' m()
méthode, j'obtiens:
(+
pour public
, -
pour private
)
Visibility bar->call() bar->callbar()
======================================================
-foo->m(), -bar->m() foo->m() bar->m()
-foo->m(), +bar->m() foo->m() bar->m()
+foo->m(), -bar->m() ERROR ERROR
+foo->m(), +bar->m() bar->m() bar->m()
(protected
semble se comporter comme public
).
Je m'attendais à tout pour se comporter comme il le fait lorsque les deux sont déclarés public
. Mais bien que foo->call()
et bar->callbar()
sont essentiellement la même chose, ils aboutissent à des résultats différents en fonction de la visibilité de m()
dans foo
et bar
. Pourquoi est-ce arrivé?
Il joue différents dans la troisième ligne du résultat,la mienne est foo->m() de la barre->m(),aucune erreur n'est survenue
Comme pour fins de clarification voici le lien à votre troisième cas, stackoverflow.com/questions/18010637/...
foo::appelez le() et le bar::callbar() ne sont pas la même chose. Ils ont des portées différentes. Champ d'application définit si vous pouvez appeler méthode privée. Penser comme ceci: méthode privée est un détail de l'implémentation de la classe, seul le code à l'intérieur de cette classe peut l'appeler.
Comme pour fins de clarification voici le lien à votre troisième cas, stackoverflow.com/questions/18010637/...
foo::appelez le() et le bar::callbar() ne sont pas la même chose. Ils ont des portées différentes. Champ d'application définit si vous pouvez appeler méthode privée. Penser comme ceci: méthode privée est un détail de l'implémentation de la classe, seul le code à l'intérieur de cette classe peut l'appeler.
OriginalL'auteur NullUserException | 2010-09-21
Vous devez vous connecter pour publier un commentaire.
Héritant/prépondérant méthodes
En PHP, les méthodes (y compris privés) dans les sous-classes sont soit:
Vous pouvez le voir avec ce code:
Maintenant, si vous substituez la méthode privée, son nouveau champ d'application ne sera pas Un, il sera B, et l'appel échouera parce que
A::callH()
s'exécute dans le champ d'applicationA
:De l'appel de méthodes
Ici, les règles sont comme suit:
bar
).Conclusion
bar->call()
, le champ d'application decall
estfoo
. L'appel de$this->m()
suscite une recherche dans la table des méthodes debar
pourm
, ce qui donne un privébar::m()
. Toutefois, la portée debar::m()
est différent de l'appel de la portée, ce quifoo
. La méthodefoo:m()
est trouvé lors de la traversée de la hiérarchie et est utilisé à la place.foo
, public dansbar
) Le champ d'application decall
est encorefoo
. La recherche de rendements publicbar::m()
. Toutefois, sa portée est marqué comme ayant changé, si une recherche est faite dans la table de fonction de l'appel de la portéefoo
pour la méthodem()
. Cela donne une méthode privéefoo:m()
avec la même portée que l'appel de la portée, de sorte qu'il est utilisé à la place.call
est encorefoo
. La recherche de rendements publicbar::m()
. Son champ d'application n'est pas marquée comme ayant changé (ils sont à la fois publics), de sortebar::m()
est utilisé.OriginalL'auteur Artefacto
Une méthode privée n'est pas substituables, comme une méthode privée n'est pas visible, même à ses sous-classes. La définition d'une méthode protégé signifie qu'il n'est pas visible à l'extérieur de la classe elle-même ou ses sous-classes.
Si vous avez une méthode que vous souhaitez utiliser à partir de votre classe parent, mais veulent des enfants pour pouvoir modifier son comportement, et ne veulent pas de cette méthode disponible à l'extérieur, utiliser
protected
. Si vous voulez des fonctionnalités à votre classe parent qui ne peut en aucun cas être modifié par les sous-classes, définit la méthode commeprivate
.EDIT: pour clarifier davantage, si vous disposez de deux méthodes avec le même nom dans l'un des parents et de la sous-classe, et ces méthodes sont définies comme privé, essentiellement de la sous-classe de la méthode n'a absolument aucun rapport avec la méthode parent. Comme l'a dit, une méthode privée est TOTALEMENT INVISIBLE à la sous-classe.
Considérez ceci:
Appel
$bar->callz()
; va produire une ERREUR, parce que z n'existe pas dans la sous-classe du tout, pas même comme une méthode héritée.bar->callbar()
se comportent de la façon dont il le fait?Lorsque
m()
dansfoo
estpublic
, puisbar
pouvez remplacerm()
. Sinon,bar
remplace rien; C'est pourquoi seul dans le 4e cas nebar->call()
résultat avec:bar->m()
lorsque vous appelez bar->callbar() c'est l'appel de bar->m. Tout simplement parce que les deux méthodes ont le même nom ne signifie pas qu'on est en train d'être remplacé (en particulier lorsqu'ils traitent avec des méthodes privées).
J'ai essayé de préciser davantage. Laissez-moi savoir si ce n'est toujours pas à résoudre votre question.
-1 Une méthode privée n'est pas totalement invisible à ses sous-classes, c'est en fait copié. Donc, ils savent qu'ils existent, ils juste ne peut pas l'appeler (le message d'erreur est encore différent).
OriginalL'auteur Sam Day
Selon le manuel PHP:
http://www.php.net/manual/en/language.oop5.visibility.php
MODIFIER
Si
m()
dansfoo
est public, il est remplaçable. Lorsque c'est le casm()
debar
remplacem()
dansfoo
.OriginalL'auteur Chris Laplante