tutorial example ejemplos classes clases abstractas php oop class extending

example - public function php



Extender clases estáticas de PHP (3)

He estado luchando en esta área durante varios días y he llegado a una conclusión, pero como la conclusión no era la que estaba buscando, antes de darme por vencido, intentaré ver lo que dicen otras personas. La fe muere el último ...

Digamos que tenemos una superclase (llamada "Super") y una subclase (llamada "Sub").

class Super { protected static $title = ''super''; public static function get_class_name() { echo __CLASS__; } public static function get_title() { echo self::$title; } } class Sub extends Super { protected static $title = ''sub''; }

Ahora, probablemente esperarías que, dado que Sub extiende Súper, ese Sub ahora heredará todos los métodos de Super, sin embargo, parece que solo recibe referencias a los métodos del Sub.

Digo esto porque si llamo:

Sub::get_class_name();

la salida es "Super", y no "Sub".

Y si llamo:

Sub::get_title();

de nuevo, la salida es "súper", e incluso tengo el $ título declarado en Sub.

Entonces, esto significa que cuando invoco una función estática heredada, el alcance de la función será la superclase, no la que se invoca (incluso si imprime la traza inversa, mostrará que la llamada se realizó en la superclase !!!), y para obtener el alcance como la subclase sobre la cual se realiza la llamada, necesito redeclarar ese método dentro de esa subclase. Bueno, este tipo de derrotas el propósito de extender las clases, ¿no?

Entonces mi pregunta es, ¿puedo alguna vez extender una clase estática, llamar a uno de los métodos heredados y tener el alcance de la subclase? o al menos para poder identificar su nombre de clase? Y si no, ¿por qué querría extender las clases estáticas?

¡Gracias!


Afortunadamente, estoy haciendo algo por mí, así que le dije, que se joda, estoy usando PHP5.3. Pero aún así, no me gusta que tenga que redeclarar "get _clase _name" en todas las clases, tal vez me extiendan como 10 clases. Así que se me ocurrió esta solución:

class Super { protected static $classname = __CLASS__; public static function get_classname($name) { static::$classname = $name; } public static function get_classname() { return static::$classname; } } class Sub1 extends Super { } class Sub2 extends Super { } class Sub3 extends Super { } $classes = get_declared_classes(); foreach($classes as $k => $v) { if (is_subclass_of($v, ''Super'')) { $v::set_classname($v); } } echo Sub1::get_classname(); // Sub1 echo Sub2::get_classname(); // Sub2 echo Sub3::get_classname(); // Sub3

Puede parecer un poco sucio, pero no creo que sea tan malo. Una vez hecho esto, finalmente puede extender los métodos estáticos sin tener que volver a declarar los métodos.


De nuevo, esto no es posible antes de PHP 5.3.0.

La conexión estática tardía se introdujo en PHP 5.3.0 y le permite hacer exactamente lo que quiere a través de la palabra clave static .

class Super { protected static $title = ''super''; public static function get_class_name() { echo __CLASS__; } public static function get_title() { echo static::$title; } } class Sub extends Super { protected static $title = ''sub''; }

get_class_name() igual devolverá Super aunque __CLASS__ siempre devuelve la clase actual en la que se declara el método que se está ejecutando (algo así como __FILE__ que siempre devuelve el archivo actual, sin importar si lo incluyó o no).

Para eso, no tienes más remedio que volver a declarar la función en la Sub .

class Super { protected static $title = ''super''; public static function get_class_name() { echo __CLASS__; } public static function get_title() { echo static::$title; } } class Sub extends Super { protected static $title = ''sub''; public static function get_class_name() { echo __CLASS__; } }


Puede utilizar get_called_class() para obtener el nombre de clase de la clase a la que llama, incluso si es estático. No tienes que declararlo en ningún lado.

Del ejemplo de Andrew:

class Super { public static function get_class1_name() { echo __CLASS__; } public static function get_title() { echo get_called_class(); } } class Sub extends Super { public static function get_class2_name() { echo __CLASS__; } } Sub::get_title(); // Echos Sub. Sub::get_class1_Name(); // echos super Sub::get_class2_Name(); // echos sub

Por lo tanto, no tiene que declarar ninguna variable.