扩展PHP静态类

时间:2009-08-14 22:25:18

标签: php oop class extending

我已经在这个领域挣扎了几天,我已经得出结论,但由于结论不是我想要的,在我放弃之前,我会试着看看其他人说的话。信仰最后死了......

假设我们有一个超类(称为“超级”)和一个子类(称为“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

所以这意味着当我调用一个继承的静态函数时,函数的作用域将是超类,而不是被调用的类(即使你打印了回溯,它也会显示调用是在超类上进行的! !),并且为了获得作为调用的子类的范围,我需要在该子类内重新声明该方法。 那么这种方法会破坏扩展课程的目的,不是吗?

所以我的问题是,我可以扩展一个静态类,调用一个继承的方法并拥有子类的范围吗?或者至少能够识别它的类名? 如果没有,我为什么要扩展静态类?

谢谢!

3 个答案:

答案 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

它可能看起来有点脏,但我不认为它那么糟糕。完成此操作后,您最终可以扩展静态方法,而无需重新声明方法。