2010-01-03 15 views
7

Si tengo una clase principal extendida por muchas otras clases, y quiero asegurarme de que SIEMPRE se ejecute el constructor de la clase padre, ¿es una mala idea declarar el constructor final?¿Es una mala práctica declarar el ctor de una clase como 'final' en PHP?

Yo estaba pensando en hacer algo como esto:

class ParentClass { 

    public final function __construct() { 

     //parent class initialization... 

     $this->construct(); 

    } 

    protected function init() { 

     echo 'constructing<br>'; 

    } 

} 

class ChildClass extends ParentClass { 

    protected function init() { 

     //child class initialization 

     echo 'constructing child<br>'; 

    } 

} 

de esa manera la clase hija puede tener una especie de constructor, y el constructor de la clase padre siempre se ejecutará. ¿Es esta mala práctica?

+0

entiendo por qué usted no confía en los programadores de PHP, pero yo no entiendo por qué te importa :-) –

+0

Sólo intento ser explícito con mi código –

Respuesta

9

Declarar un final__construct garantiza que nadie que extienda su clase pueda implementar un método con el mismo nombre. En la superficie, parecería que nadie más puede declarar un constructor para las subclases de esta clase, pero esto no es cierto, ya que el estilo PHP 4 de ClassName() todavía funciona bien como nombre alternativo para el constructor Entonces realmente, declarar un constructor como final no te da nada en PHP.

+0

es verdad, no lo había considerado.¿Aún así se llamaría el método '__construct 'de la clase padre? ¿O el constructor de la clase secundaria de un nombre diferente lo anularía? –

+1

Los constructores principales nunca se llaman automáticamente. Todavía tendría que llamar 'parent :: __ construct()' o 'parent :: ClassName()' en el constructor de clase hijo. – Mike

-1

Después de finalizar el constructor, no puede pasar ninguna variable a la función de inicialización. Obliga a los usuarios de su clase a usar globales como configuraciones para sus clases secundarias.

En Zend Framework, usar el método de escritura invalidado() es una práctica común, pero nunca he visto finalizar un constructor allí.

+0

¿De verdad? Lo intenté y pude pasar una variable del constructor finalizado a la función de inicialización secundaria y repetirlo –

+1

oh, quiero decir, el usuario no puede pasar ningún parámetro imprevisto –

+0

Sin embargo, ZF está pasando a pasar alrededor de los objetos de configuración como un medio de estandarizar cómo se pasan los parámetros entre los objetos. –

3

A partir de PHP 5.3.3, he probado esto con 5.6 y 7.0, declarando el método de una clase final__construct evitará cualquier clase hija anulando el constructor, ya sea usando __construct o el estilo PHP 4 de ClassName() (nótese que la El estilo PHP 4 está en desuso a partir de PHP 7). La prevención de una clase secundaria que declare un constructor asegurará que siempre se llame al constructor padre. Esto, por supuesto, no permitirá que ninguna clase secundaria implemente su propia lógica de constructor. Definitivamente habría casos de uso práctico para esto, aunque no lo recomendaría como una buena práctica en general.

Algunos ejemplos:

sin declarar __construct última

class ParentClassWithoutFinal { 
    private $value = "default"; 

    public function __construct() { 
     $this->value = static::class; 
    } 

    function __toString() { 
     return $this->value; 
    } 
} 

class ChildClassA extends ParentClassWithoutFinal { 
    public function __construct() { 
     // Missing parent::__construct(); 
    } 
} 

echo (new ChildClassA()); // ouput: default 

con Final __construct

class ParentClassWithFinal extends ParentClassWithoutFinal { 
    public final function __construct() { 
     parent::__construct(); 
    } 
} 

class ChildClassB extends ParentClassWithFinal { 
} 

echo (new ChildClassB()); // output: ChildClassB 

Tratando de declarar __construct en una clase hija

class ChildClassC extends ParentClassWithFinal { 
    public function __construct() { 
    } 
} 

// Fatal error: Cannot override final method ParentClassWithFinal::__construct() 

Tratando de declarar ClassName() constructor en una clase hija

class ChildClassD extends ParentClassWithFinal { 
    public function ChildClassD() { 
    } 
} 

// Fatal error: Cannot override final ParentClassWithFinal::__construct() with ChildClassD::ChildClassD() 
// Also in PHP 7: Deprecated: Methods with the same name as their class will not be constructors in a future version of PHP; ChildClassD has a deprecated constructor 
Cuestiones relacionadas