2012-04-09 14 views
6

Estoy tratando de extender una clase de PHP sin reescribir todo. Aquí está un ejemplo:¿Cómo puede una clase PHP que se extiende a otra heredar una función privada?

<? 
$a = new foo(); 
print $a->xxx(); 
$b = new bar(); 
print $b->xxx(); 

class foo { 
    const something = 10; 

    public function xxx() { 
    $this->setSomething(); 
    return $this->something; 
    } 

    private function setSomething() { 
    $this->something = self::something; 
    } 
} 

class bar extends foo { 

    public function xxx() { 
    $this->setSomething(); 
    $this->something++; 
    return $this->something; 
    } 

} 
?> 

Sin embargo cuando corro el guión me sale el siguiente error:

Fatal error: Call to private method foo::setSomething() from context 'bar' in test.php on line 23 

parecería que la barra no está heredando la setSomething función privada(). ¿Cómo arreglaría esto sin modificar la clase foo?

+0

No puede cambiar 'setSomething()' a 'protected'? – alex

+0

Como dije anteriormente, la clase foo no debe modificarse. ¿De qué otra manera puedo hacer esto? –

+0

Utiliza la herramienta adecuada para el trabajo, es decir, "protegida". – alex

Respuesta

4

bar es heredar la función está bien, pero no se puede llamar. Ese es el objetivo de los métodos private, solo la clase declarante puede llamarlos.

+0

Entonces, ¿tendría que redefinir explícitamente setSomething() en mi clase de barra? –

+1

Sí, ese es el método * cuerdo * para hacer esto. – deceze

+5

Mejor método es usar protegido en la clase principal;) de esta manera se mantiene privado desde el exterior, pero la clase "hija" puede acceder a él. –

6

Los miembros privados no son heredables, no puede usarlos en la subclase. No son accesibles fuera de la clase.

Debe tener que realizar esa función como protegida o pública. Los miembros protegidos son accesibles para esa clase y para la clase heredada. Entonces, tu mejor opción es hacer que esa función sea protegida.

+0

Como dije anteriormente, la clase foo no debe modificarse. ¿De qué otra manera puedo hacer esto? –

+0

@KennethVogt: No tiene opciones aquí. –

13

No, no se puede arreglar esto sin modificar la clase foo. Debido a que una clase heredada no puede acceder a los miembros privados de la clase principal. Es una regla muy básica .

Declare setSomething() como protected. Estará resuelto.

Ver manual

+0

Como dije anteriormente, la clase foo no debe ser modificada. ¿De qué otra manera puedo hacer esto? –

+0

No puede hacerlo mientras mantenga oop. –

0

Sin modificar la clase original, no hay forma de que la clase heredada llame directamente a los métodos private de la clase principal.

0

¿Usted intentó esto?

class bar extends foo { 

    public function xxx() { 
     $this->something = parent::xxx(); 
     $this->something++; 
     return $this->something; 
    } 
} 

Nota del padre :: xxx(); es público, por lo que debería funcionar ... aunque parezca una llamada estática.

Cuestiones relacionadas