2010-01-09 17 views
5

Pregunta editada para reflejar mejor mis necesidades.Llamando a Parent Class Methods


Tome el ejemplo siguiente:

class Base 
{ 
    public $Text = null; 

    public function __construct() 
    { 
     $this->Text = new Base_Text(); 
    } 
} 

class Base_Text extends Base 
{ 
    public $Is = null; 

    public function __construct() 
    { 
     $this->Is = new Base_Text_Is(); 
    } 

    public function CammelCase($string) 
    { 
     return trim(str_replace(' ', '', ucwords($string))); 
    } 
} 

class Base_Text_Is extends Base_Text 
{ 
    public function CammelCase($string) 
    { 
     return ($string === $this->CammelCase($string)); // doesn't work 
    } 
} 

Como puedo fijar el método Base_Text_Is::CammelCase() sin llamar a la clase Base_Text estáticamente (no usar parent:: o Base_Text::)?

La única solución que se me ocurrió para este tipo de situaciones es crear una función Singleton así:

function Base() 
{ 
    static $instance = null; 

    if (is_null($instance) === true) 
    { 
     $instance = new Base(); 
    } 

    return $instance; 
} 

Y cambiar el método de Base_Text_Is::CammelCase() a esto:

return ($string === Base()->Text->CammelCase($string)); 

Y con el fin para evitar crear dos instancias de objetos de la clase Base, en lugar de hacer:

$base = new Base(); 
$base->Text->Is->CammelCase('MethodOverloading'); // true 

acabo de hacer:

Base()->Text->Is->CammelCase('MethodOverloading'); // true 

Es esta una buena práctica? ¿Hay alguna otra solución?

+0

I don' Obtenga su último comentario en la respuesta de Darrell. ¿No puedes acceder a las propiedades no estáticas de 'Base_Text'? ¿Desde dónde quieres llamarlos? Creo que deberías explicar esto más. –

+0

@Felix: trato de mantener el ejemplo lo más simple posible, hay casos en los que no puedo llamar a un método principal de forma estática porque depende de las propiedades creadas. –

Respuesta

7

El corazón de su pregunta se encuentra aquí:

¿Cómo puede el hijo :: B() llamar al papá :: A() método no estático (sin utilizar padre o papá)?

La respuesta es simple, no puede. Sobrepasó Dad::A() con Son::A(). El único concepto de A() que tiene ahora el objeto Son es su propio A(). Tendría que llamar al método primario estáticamente, o en una instancia de objeto Dad completamente diferente.

La línea inferior es, si desea llamar al método padre A(), ¿por qué se molesta en anularlo en primer lugar?

Su estructura no tiene ningún sentido tampoco. ¿Por qué querría una llamada al $dad->A() pasándola al $dad->son->A(), que a su vez llamaría al $dad->son->B(), que luego, por lo que está preguntando, llama al $dad->A() nuevamente? Eso es un ciclo infinito.

Su enfoque singleton no parece ofrecer ninguna ventaja real más que asegurarse de no crear más de un objeto padre, pero el hecho es que aún está instanciando un objeto completamente separado para realizar una lógica que suena como debería estar dentro de la clase y no afuera.

Sin ver la lógica real y lo que está tratando de lograr, es difícil saber qué recomendar para evitar esta dependencia circular. Sin embargo, creo que es posible que desee analizar lo que está tratando de hacer con estos métodos y tal vez rediseñar cómo funciona la herencia.

EDITAR

creo que tenga demasiada herencia pasando. No hay ninguna razón que usted debe hacer esto:

$base = new Base(); 
$base->Text->Is->CammelCase('MethodOverloading'); // true 

Si toda la funcionalidad está en las clases hijas, que no se debe crear instancias de la clase Base. Debe ser algo como esto:

$text = new Text(); 
$text->isCamelCase('someString'); 

Su código se puede simplificar en gran medida, con todos los padres ejemplificaciones circulares/niños retirados y la funcionalidad específica empujado hacia abajo a las clases hijas:

class Base 
{ 
    //don't put anything related to child classes here, 
    //unless it is going to provide specific functionality 
} 

class Text extends Base 
{ 
    public function CamelCase($string) 
    { 
     return trim(str_replace(' ', '', ucwords($string))); 
    } 

    public function isCamelCase($string) 
    { 
     return ($string === $this->CamelCase($string)); 
    } 
} 
+0

Es un ejemplo hipotético, por supuesto, y sé que es un ciclo infinito. Sin embargo, he encontrado aplicaciones útiles en el mundo real para esto y siempre he usado la solución que proporcioné en mi pregunta. Me preguntaba si podría haber una mejor alternativa. –

+0

He actualizado la pregunta para dar un ejemplo más realista y abordar algunos de los problemas que refiere, como "instanciar un objeto completamente separado". Espero que sea un poco más claro ahora. –

+0

@zombat: Solo me gustaría preguntar, a la luz de mi última edición, si aún crees que el rediseño de la herencia es una buena idea (en caso afirmativo, ¿algún puntero?) Y si se usa la función singleton 'Base()' una mala práctica en este escenario. –

1

No creo que haya una forma de llamar a un método principal desde el niño sin llamarlo estáticamente o usando parent::. Sin embargo, puedo estar malinterpretando la pregunta. La creación de una instancia de Son() no crea dos objetos. El hijo extiende a papá, pero sigue siendo un solo objeto.

Si va a llamar a papá() con un Singleton dentro de Hijo, ¿por qué extenderlo de Son?

+0

He actualizado mi pregunta con un ejemplo más realista, por favor míralo. –

+0

Todavía no entiendo tu aversión a usar 'parent ::'. –

+0

No es una aversión, simplemente no puedo usarlo porque si lo hago no podré acceder a las propiedades no estáticas 'Base_Text'. –