texto - Herencia y visibilidad-PHP
string strip_tags (6)
Tengo dificultades para entender por qué obtenemos la salida de este código:
<?php
class Bar
{
public function test() {
$this->testPrivate();
$this->testPublic();
}
public function testPublic() {
echo "Bar::testPublic/n";
}
private function testPrivate() {
echo "Bar::testPrivate/n";
}
}
class Foo extends Bar
{
public function testPublic() {
echo "Foo::testPublic/n";
}
private function testPrivate() {
echo "Foo::testPrivate/n";
}
}
$myFoo = new foo();
$myFoo->test();
?>
Así que Foo extiende Bar. $ myfoo es un objeto de la clase Foo. Foo no tiene un método, llamado test (), por lo que lo extiende desde su barra principal. Pero por qué el resultado de test () es
Bar::testPrivate
Foo::testPublic
¿Me pueden explicar por qué el primero no es Foo :: testPrivate, cuando el método de este padre se invalida en el niño?
¡Muchas gracias por adelantado!
Del manual :
Los miembros declarados como privados solo pueden ser accedidos por la clase que define al miembro.
Cuando la función de prueba se ejecute en la barra de clase base, accederá a la función privada en su propia clase.
Esto no es específico de PHP Las reglas de herencia exigen que las funciones protegidas y públicas sean anulables. Las funciones privadas tienen su propio alcance y son invisibles para la clase generalizada.
A continuación encontrará la misma situación en Java, mismo resultado:
Bar::testPrivate
Foo::testPublic
Excepto que podría recibir una advertencia
The method testPrivate() from the type Foo is never used locally Foo.java
ya que se compila java.
public class Bar
{
public void test() {
this.testPrivate();
this.testPublic();
}
public void testPublic() {
System.out.println("Bar::testPublic/n)");
}
private void testPrivate() {
System.out.println( "Bar::testPrivate/n");
}
}
public class Foo extends Bar {
public void testPublic() {
System.out.println("Foo::testPublic/n");
}
private void testPrivate() {
System.out.println("Foo::testPrivate/n");
}
public static void main(String[] args) {
Foo myFoo = new Foo();
myFoo.test();
}
}
Los métodos privados no son visibles para nada más que la clase declarante. Como llama a testPrivate
desde la clase padre, el único método al que tiene acceso es su propia declaración del método. Así obtienes la salida que ves. Sin embargo, si el modificador de acceso estuviera protected
, obtendría la salida que espera, ya que los métodos protegidos son visibles a lo largo de la cadena de herencia.
Porque private
significa private
. Ninguna otra clase, ni siquiera las clases de niños conocen Bar::testPrivate()
y, por lo tanto, no pueden anular algo que ni siquiera conocen.
Puedes usar Foo::testPrivate()
solo dentro de Foo
. Porque de eso se trata lo private
.
Más información: Comportamiento extraño al anular métodos privados.
Probablemente, debido a que testPrivate
es, como su nombre lo sugiere, un método privado y no se heredará / sobrescribirá por herencia de clase.
En la página de manual de php.net probablemente obtuviste ese código explícitamente que We can redeclare the public and protected method, but not private
Entonces, lo que sucede exactamente es lo siguiente: la clase secundaria no volverá a testPrivate
el método testPrivate
sino que crea su propia versión en el "ámbito", solo si el objeto secundario. Como test()
se define en la clase padre, accederá al testPrivate
los padres.
Si desea volver a declarar la función de test
en la clase secundaria, ¿debería acceder a los elementos secundarios ? testPrivate()
? testPrivate()
.
private
miembros private
no pueden ser anulados, solo los públicos y protegidos pueden. Esto significa que, de hecho, testPrivate
no se testPrivate
, por lo que Bar
no puede verlo y aún llama a su propio testPrivate
.