我已经在这个领域挣扎了几天,我已经得出结论,但由于结论不是我想要的,在我放弃之前,我会试着看看其他人说的话。信仰最后死了......
假设我们有一个超类(称为“超级”)和一个子类(称为“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';
}
现在,你可能会期望,因为Sub扩展了Super,Sub现在将继承所有Super的方法,但是,它似乎只接收Sub的方法的引用。
我这样说是因为如果我打电话:
Sub::get_class_name();
输出为“超级”,而不是“子”。
如果我打电话:
Sub::get_title();
再次,输出是“超级”,我甚至在Sub。
中声明了$ title所以这意味着当我调用一个继承的静态函数时,函数的作用域将是超类,而不是被调用的类(即使你打印了回溯,它也会显示调用是在超类上进行的! !),并且为了获得作为调用的子类的范围,我需要在该子类内重新声明该方法。 那么这种方法会破坏扩展课程的目的,不是吗?
所以我的问题是,我可以扩展一个静态类,调用一个继承的方法并拥有子类的范围吗?或者至少能够识别它的类名? 如果没有,我为什么要扩展静态类?
谢谢!
答案 0 :(得分:30)
同样,在PHP 5.3.0之前,这是不可能的。
PHP 5.3.0中引入了 Late Static Binding,允许您通过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()
仍会返回Super
,但__CLASS__
总是返回正在运行的方法的当前类(类似于__FILE__
,它总是返回当前文件无论你是否包括它。)
为此你没有别的选择,只能在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__;
}
}
答案 1 :(得分:3)
您可以使用get_called_class()
来获取您正在调用的类的类名,即使它是静态的。你不必在任何地方声明它。
来自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
因此,您不必声明任何变量。
答案 2 :(得分:0)
幸运的是,我正在为我做点什么,所以我说,拧紧它,我正在使用PHP5.3。但即使这样,我也不喜欢我必须在每个班级重新声明“get _class _name”,也许我正在扩展到10个班级。所以我提出了这个解决方案:
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
它可能看起来有点脏,但我不认为它那么糟糕。完成此操作后,您最终可以扩展静态方法,而无需重新声明方法。