2010-06-20 92 views
28

Me preguntaba si es posible llamar a los padres __construct(), antes del __construct() del hijo con la herencia en PHP.Llamar al constructor padre antes del constructor hijo en PHP

Ejemplo:

class Tag { 
    __construct() { 
     // Called first. 
    } 
} 

class Form extends Tag { 
    __construct() { 
     // Called second. 
    } 
} 

new Form(); 

Idealmente, me gustaría ser capaz de hacer algo entre ellos. Si esto no es posible, ¿hay alguna alternativa que me permita hacer esto?

La razón por la que quiero hacer esto es poder cargar una serie de configuraciones predeterminadas específicas de la etiqueta que Form puede usar cuando se llama a __construct().

EDITAR: Perdón, olvidé agregar esto .. Prefiero no llamar a la clase para padres de la clase de niños. Es simplemente porque expone algunos datos privados (para los padres) para el niño, cuando se pasa como argumento

Esto es lo que quiero hacer:

$tag = new Tag($privateInfo, $publicInfo); 
$tag->extend(new Form()); // Ideal function, prob doesn't work with inheritance. 

Tag.php

class Tag { 
    private $privateInfo; 
    public $publicInfo; 
    __construct($private, $public) { 
     $this->privateInfo = $private; 
     $this->publicInfo = $public; 
    } 
} 

form.php

class Form extends Tag { 

    __construct() { 
     echo $this->publicInfo; 
    } 
} 

¿Tiene sentido?

Gracias! Matt Mueller

+0

¿Puede explicar lo que quiere decir con esto * 'expone algunos datos privados (para el padre) al niño' *? –

+2

Los datos privados de una clase principal no estarán expuestos a ninguna subclase. Los datos públicos o protegidos serán privados. –

+0

Yah, pero si los parámetros (privados) pasan primero por el constructor hijo, el niño tiene acceso a ellos. Lo edité para aclararlo. – Matt

Respuesta

46

Sólo tiene que llamar a parent :: __ construct en el niño.

class Form extends Tag 
{ 
    function __construct() 
    { 
     parent::__construct(); 
     // Called second. 
    } 
} 
+1

Ahh lo siento. Olvidé agregar que preferiría no tener eso en el constructor del niño. Por favor, lea editar. – Matt

+0

Decidió que esta era la mejor de las alternativas. Desafortunadamente, no es exactamente lo que quería, bueno ... ¡Gracias! – Matt

+0

¡Oh, guau, Denis, me has estado ayudando en los últimos días ... Gracias, amigo! – Matt

3

sí solo llame parent::__construct() en su construcción

+0

Ahh lo siento Olvidé incluir un requisito ... Por favor, lea la edición para la actualización. – Matt

+2

Esta es la manera de hacerlo, simplemente lea el manual de OOP si no está de acuerdo. No trates de reinventar la rueda. Si le preocupa su modelo, intente publicarlo también para ver cómo lo hizo. Probablemente estés haciendo una mala técnica de diseño. – Pentium10

+0

No estoy tratando de reinventar la rueda ... Estoy tratando de encontrar una solución a mis requisitos. – Matt

3

Sí, pero sólo a nivel interno (es decir, escribiendo una extensión de PHP), así que si yo fuera usted me conformaría con llamar parent::__construct(). Ver this section en la wiki de PHP.

Lo sentimos, PHP no es Java. Creo que no requerir (implícita o explícitamente) que se llame al superconstructor fue una decisión de diseño muy pobre.

1

Por lo que suena, es posible que desee replantear su diseño para que no tenga que pasar los parámetros en el constructor. Si no crees que se puede hacer, hazlo como una pregunta, es posible que te sorprendan algunas de las sugerencias.

La clase secundaria tiene la capacidad de anular el constructor principal sin llamarlo en absoluto. Yo recomendaría tener un método final en la clase para padres. De esta forma, todos saben que no desea que se anule esta opción, y cualquier clase heredada (con razón) tiene acceso para hacer lo que quiera en el constructor.

class Father { 
    private $_privateData; 
    final function setPrivateData($privateData) { 
     $this->_privateData = $privateData; 
    } 
} 

Otro, no se recomienda, más "reinventar la rueda", la solución sería definir una función en la clase padre, dicen _construct(), que se llama en su propia construcción. No es muy claro, no usa características de lenguaje/construcciones, y es muy específico para una sola aplicación.

Una última cosa a tener en cuenta: realmente no se puede ocultar información de la clase secundaria.Con Reflection, serialize, var_dump, var_export y todas estas otras API útiles en el lenguaje php, si hay un código que no debería hacer nada con los datos, entonces no hay mucho que pueda hacer para evitar almacenarlo. Hay bibliotecas y otras que ayudan a crear cajas de arena, pero es difícil aislar un objeto de sí mismo.

Editar: De alguna manera me perdí la respuesta de Artefacto, y supongo que tiene razón (nunca he intentado escribir una extensión para hacer eso). Aún así, su implementación rompe las expectativas del desarrollador al dificultar ver el código para explicar lo que está sucediendo.

+0

Oye, gracias por tu respuesta. Lamentablemente, este tema se salió un poco de la mano, que es mi culpa. De todos modos, estoy tratando de rediseñarlo. Tengo una pregunta sobre tu respuesta ... ¿cómo puedes hacer esto? "La clase hija tiene la capacidad de anular el constructor padre sin llamarlo para nada". – Matt

+0

@Matt No puede usar solo código PHP. La persona que escribe la clase derivada tiene la capacidad de no llamar al constructor padre en absoluto. Lo que podrías hacer por un proyecto es tener definida otra función que sea llamada por la clase padre en su constructor, por ejemplo _construct() que el padre define y llama. – Reece45

Cuestiones relacionadas