2011-06-14 12 views
21

Cuando intento anular la variable de clase de la misma manera que anula el método de clase en PHP. Me gusta:Reemplazo de variable de PHP

class DataMapper { 
    protected $_name = null; 

    public function printName() { 
      echo $this->_name; 
    } 
} 

class Model extends DataMapper { 
    protected $_name = 'Ana'; 
} 

$test = new Model(); 
$test->printName(); 

Se imprime 'Ana'.

¿Por qué PHP puede hacer una cosa así? Rompe la ley del paradigma orientado a objetos

+1

No creo que el comportamiento del idioma sea ilegal en ninguna jurisdicción. Las variables en realidad no necesitan ser sombreadas. Y en PHP los objetos son simplemente diccionarios también. Solo redeclara el valor predeterminado aquí. – mario

+5

Esas no son variables de clase (es decir, 'estáticas'), son variables de objeto/instancia. Como explican las personas, así es como se supone que la herencia funciona con los miembros protegidos. Si en cambio establecieras una variable de clase privada (es decir 'private static $ myVar = 'Ana';') entonces no se definiría en ninguna clase secundaria. – joelhardi

+0

Según entiendo, tienes razón. Normalmente no puede anular las variables. Y aquí no estás realmente haciendo eso, simplemente estás redeclarando una variable, y el original está perdido. Creo, de todos modos. Creo que PHP es un poco más flexible en sus estándares y le permite salirse con operaciones/sintaxis cuestionables. – Jonathon

Respuesta

25

No lo es. Así es como se supone que PHP funciona. Eche un vistazo al PHP Classes and Objects Visibility.

Los objetos del mismo tipo tendrán acceso a los demás miembros privados y protegidos aunque no sean las mismas instancias. Esto se debe a que los detalles específicos de implementación ya se conocen cuando están dentro de esos objetos.

Dado que Model extiende DataMapper, tiene acceso a sus funciones, variables y demás, pero puede anularlas, que es lo que sucedió. Aunque su función reside en la clase DataMapper, se llama desde (y es heredada por) la clase Model en la que el nombre se establece en Ana.

+0

guau respuesta muy agradable, me pregunto si PHP puede hacer esto. He intentado con el código relevante en C++, C# y JAVA pero no tuve suerte – brian

+0

@brian, PHP puede hacer esto, que es un lenguaje que permite anulación variable; Java solo admite el ocultamiento de variables, por lo que obtendrá resultados diferentes. – MengT

3

No creo que esto rompa la "ley de OO". Has heredado la clase DataMapper. Y así has ​​heredado la función pública printName(). Entonces, cuando llamas a la función, actúa como la función que pertenece a la clase de modelo.

4

Creo que solo tiene problemas para entender qué $ esto hace. Cuando hace referencia a $ this, en realidad está haciendo referencia al objeto actual.

Al heredar la clase DataMapper, se puede acceder al método printName() dentro de los objetos del Modelo, pero $ this reference todavía se refiere al objeto Model actual, $ test.

Dado que la propiedad $ _name de los objetos Model se instancia a "Ana", se está imprimiendo Ana. Esto es exactamente lo que se espera. Tal vez tener otra lectura de las teorías de Herencia y Alcance lo ayude a comprender lo que está sucediendo aquí.

+0

sí, pero en otro lenguaje como C++, C# y java no puede hacer eso. Me refiero a anular la variable de clase – brian

+1

@brian en C# que pueda, solo tiene que ser explícito de que tiene la intención de anularla. de lo contrario, simplemente oculta la variable padre de ese ámbito hacia abajo. la diferencia en PHP es que el 'override' es implícito. – drzaus