我有一个只使用静态方法扩展类的子类。我想让这个子类成为单例而不是静态因为原始开发人员真的想要一个单例但是使用静态代替(显而易见的是因为静态类中的每个方法都调用了Init()函数(基本上是构造函数))。
父级中的大多数方法都不需要在子级中覆盖,但我希望避免编写这样的方法:
public function Load($id)
{
return parent::Load($id);
}
当我不想覆盖该方法时,只需使用:
$child->Load($id);
是否可以非静态地调用静态方法?是否可以使用实例对象扩展静态对象?我知道我可以尝试它,它可能会起作用(PHP非常宽容),但我不知道是否有任何我应该关注的事情。
答案 0 :(得分:9)
是
是的,但只有从PHP 5.3开始,它们才能正常运行:http://www.php.net/manual/en/language.oop5.static.php(即。self
绑定到实际的类而不是它定义的类。)
是的,但会丢失$this
。你还没有收到警告,但也没有理由以错误的方式调用它。
答案 1 :(得分:9)
两部分答案。
首先,关于名义上的问题:非静态地调用静态方法是完全正确的; @SamDark的评论是正确的。它不会产生警告,也不会导致任何小猫谋杀。试试吧:
<?php
class test {
public static function staticwarnings(){
echo "YOU ARE (statically) WARNED!\n";
}
}
error_reporting(E_ALL);
$test = new test();
echo "\n\ncalling static non-statically\n";
$test->staticwarnings();
如果您在该静态方法中有实例引用$this
,那么您将收到致命错误。但不管你怎么称呼它都是如此。
再一次,没有警告,也没有任何小猫被杀。
答案的第二部分:
从覆盖的子类调用重写的父函数需要一个名为"scope resolution"的东西。 OP在他们的方法中做的是不调用静态方法。 (或者至少,它不是必须的;我们无法看到父实现)。关键是,使用parent关键字不是静态调用。在显式父类名称上使用::
运算符也不是静态调用,如果它是从扩展类中使用的。
为什么文档链接如此奇怪?它实际上是希伯来语。如果您遇到过与之相关的错误,您可能会发现令人愉快的解析器错误代码T_PAAMAYIM_NEKUDOTAYIM
。