7

为什么在此示例中对非静态方法的“自我”调用有效?

class A{

    protected function aNonStaticMethod(){
        return __class__;
    }

    public function aEcho(){
        echo self::aNonStaticMethod();
    }
}

感谢您的解释。

4

2 回答 2

7

在您的简单示例中, $this 和 self 是可以互换的。但是请注意处理继承时解决的不同方法(为了完整性,我添加了静态):

class A {
    protected function aNonStaticMethod(){
        return __class__;
    }

    public function selfEcho(){
        echo self::aNonStaticMethod();
    }

    public function staticEcho(){
        echo static::aNonStaticMethod();
    }

    public function thisEcho(){
        echo $this->aNonStaticMethod();
    }
}

class B extends A {
    protected function aNonStaticMethod(){
        return __class__;
    }
}

$b = new B();
$b->selfEcho(); // A
$b->staticEcho(); // B
$b->thisEcho(); // B
于 2014-01-23T15:43:59.220 回答
6

静态调用非静态方法

理论上它不应该工作,但正如这个评论所说:

php4 中没有 static 关键字,但 php4 确实允许静态调用。为了保持向后兼容性,当在 php5 中添加 static 关键字时,保留了这一点。

官方 php.net wiki支持此评论:

如果调用是从实例方法发生的,那么这已经被弃用了。不将方法注释为静态是过时的 PHP4 主义。

你真的不应该静态地调用非静态方法——它没有意义(如果有static关键字)。

完全避免静态调用非静态方法!

...因为 a) 这是一种不好的方法,并且 b) PHP 文档说:

注意
在 PHP 5 中,静态调用非静态方法会生成 E_STRICT 级别的警告。

警告
在 PHP 7 中,不推荐静态调用非静态方法,并且会生成 E_DEPRECATED 警告。将来可能会删除对静态调用非静态方法的支持。

使用::运算符进行非静态调用 - 可能是一个好方法!

正如@Kontrollfreak 指出的那样,正如本文档所说,::操作员不仅限于静态调用:

双冒号, 是允许访问 类的静态、常量和重写属性或方法的标记

因此,如果您以这种方式引用父类中的方法或属性,可以 -不限于直接父类。

编辑:不要把它误认为是 Fascade 等软件模式!

在写这个答案的过程中,我忘了提到在某些情况下,调用是静态的,但在内部调用的是动态方法——有关更多信息,请参见FacadeSingleton等模式。
但是,不要将这些与上述问题混淆!(上面的问题是关于在应该动态调用的动态事物上使用直接静态调用,这些模式是关于静态调用静态方法,然后可以动态调用动态(内部)的东西)。

于 2016-03-11T10:34:35.870 回答