19

这几天我一直在这方面苦苦挣扎,我得出了一个结论,但由于结论不是我想要的,所以在我放弃之前,我会尝试看看其他人怎么说。信仰最后死去……

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

输出是“Super”,而不是“Sub”。

如果我打电话:

Sub::get_title();

再次,输出是“超级”,我什至在 Sub 中声明了 $title。

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

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

谢谢!

4

3 回答 3

32

同样,这在 PHP 5.3.0 之前是不可能的。

后期静态绑定static是在 PHP 5.3.0 中引入的,它允许您通过关键字完全执行您想要的

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__;
    }
}
于 2009-08-14T22:39:06.757 回答
3

你可以用来get_called_class()获取你正在调用的类的类名,即使它是静态的。您不必在任何地方声明它。

从安德鲁的例子:

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

因此,您不必声明任何变量。

于 2009-08-15T01:00:37.367 回答
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

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

于 2009-08-15T12:17:20.007 回答