Seltsames Verhalten beim überschreiben der privaten Methoden
Betrachten Sie die folgende Stück code:
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();
Nun, die änderung der Sichtbarkeit des m()
Methode, die ich bekomme:
(+
für public
, -
für 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
scheint sich zu Verhalten wie public
).
Ich hatte erwartet, alles zu Verhalten, wie es tut, wenn beide erklärten public
. Aber obwohl foo->call()
und bar->callbar()
sind im wesentlichen die gleiche Sache, Sie ergeben auch unterschiedliche Ergebnisse, je nach der Sichtbarkeit der m()
im foo
und bar
. Warum geschieht dieses?
InformationsquelleAutor der Frage NullUserException | 2010-09-21
Du musst angemeldet sein, um einen Kommentar abzugeben.
Vererben/überschreiben von privaten Methoden
In PHP, Methoden (auch privat) in die Unterklassen sind entweder:
Können Sie sehen, mit diesem code:
Wenn Sie jetzt überschreiben Sie die private Methode, die neue Möglichkeiten nicht Ein, wird es B sein, und der Aufruf schlägt fehl, weil
A::callH()
läuft im RahmenA
:Aufrufen von Methoden
Hier die Regeln sind wie folgt:
bar
).Abschluss
bar->call()
den Umfang dercall
istfoo
. Aufruf$this->m()
löst eine Suche in der Methode Tabellebar
fürm
woraus sich eine privatebar::m()
. Allerdings ist der Anwendungsbereichbar::m()
unterscheidet sich von der Berufung des Umfangs, in demfoo
. Die Methodefoo:m()
gefunden wird bei der Traversierung der Hierarchie nach oben und wird stattdessen verwendet.foo
öffentliche inbar
) für den Umfang Dercall
nochfoo
. Die lookup ergibt den öffentlichenbar::m()
. Jedoch, ist Ihr Anwendungsbereich gekennzeichnet ist, verändert, so dass ein lookup gemacht wird in der Funktion die Tabelle des aufrufenden Bereichsfoo
für die Methodem()
. Dies führt zu einer privaten Methodefoo:m()
mit den gleichen Anwendungsbereich wie die aufrufenden Bereichs, so ist es stattdessen verwendet werden.call
nochfoo
. Die lookup ergibt den öffentlichenbar::m()
. Sein Anwendungsbereich ist nicht als markiert haben sich geändert (Sie sind beide public), sobar::m()
verwendet wird.InformationsquelleAutor der Antwort Artefacto
Einer privaten Methode ist nicht überschreibbare, wie eine private Methode ist nicht sichtbar, auch Ihrer Unterklassen. Die Definition einer Methode als protected bedeutet, es ist nicht sichtbar von außerhalb der Klasse selbst oder eine Ihrer Unterklassen ist.
Wenn Sie haben eine Methode, die Sie verwenden möchten, aus Ihrer übergeordneten Klasse, aber wollen, dass Kinder in der Lage, ändern Sie Ihr Verhalten, und nicht wollen, dass diese Methode extern zur Verfügung, verwenden Sie
protected
. Wenn Sie möchten, dass die Funktionalität in Ihre übergeordnete Klasse, die nicht in irgendeiner Weise verändert werden, die von Unterklassen definieren Sie die Methode wieprivate
.EDIT: zur weiteren Klärung, wenn Sie zwei Methoden mit dem gleichen Namen in einer Eltern-und Unterklasse, und diese Methoden werden als "persönlich" definiert, die im wesentlichen der Unterklasse die Methode hat absolut keinen Bezug zu den übergeordneten Methode. Wie gesagt, eine private Methode ist VÖLLIG UNSICHTBAR für die Unterklasse.
Bedenken Sie:
Aufrufen
$bar->callz()
; wird ein FEHLER erzeugt, da z nicht in der Unterklasse auf, nicht selbst als eine geerbte Methode.InformationsquelleAutor der Antwort Sam Day
Laut dem PHP-manual:
http://www.php.net/manual/en/language.oop5.visibility.php
BEARBEITEN
Wenn
m()
imfoo
ist öffentlich, es ist überschreibbare. Wenn dies der Fall istm()
ausbar
überschreibtm()
imfoo
.InformationsquelleAutor der Antwort Chris Laplante