7

我有一个子类,它扩展了一个只有静态方法的类。我想让这个子类成为单例而不是静态的,因为最初的开发人员真的想要一个单例,但使用了静态(很明显,因为静态类中的每个方法都调用 Init() 函数(基本上是构造函数))。

父级中的大多数方法不需要在子级中覆盖,但我想避免编写这样的方法:

public function Load($id)
{
     return parent::Load($id);
}

当我不想完全覆盖该方法而只使用:

$child->Load($id);

是否可以非静态地调用静态方法?是否可以使用实例对象扩展静态对象?我知道我可以尝试它并且它可能会起作用(PHP 非常宽容),但我不知道是否有什么我应该担心的。

4

2 回答 2

11
  • 你能继承静态方法吗?

是的

  • 你能覆盖静态方法吗?

是的,但只有从 PHP 5.3 开始,它们才能按您的预期工作: http ://www.php.net/manual/en/language.oop5.static.php (即self绑定到实际类而不是它所在的类中定义)。

  • 是否可以非静态地调用静态方法?

是的,但会输$this。您(还)没有收到警告,但也没有真正的理由将其称为错误的方式。

于 2013-03-29T16:20:13.833 回答
11

分两部分回答。

首先,关于名义上的问题:非静态调用静态方法非常好;@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在该静态方法中有一个实例引用 , ,那么您将收到一个致命错误。但不管你怎么称呼它都是真的。

再一次,没有警告,也没有任何小猫被杀。


答案的第二部分:

Calling an overridden parent function from an overriding child class requires something called "scope resolution". What the OP is doing in their method is NOT calling a static method. (Or at least, it doesn't have to be; we can't see the parent implementation). The point is, using the parent keyword is not a static call. Using the :: operator on an explicit parent class name is also not a static call, if it is used from an extending class.

Why is that documentation link so strangely named? It's literally Hebrew. If you've ever run into an error related to it, you might have observed the delightfully-named parser error code T_PAAMAYIM_NEKUDOTAYIM.

于 2015-09-23T18:29:37.347 回答