如何使用 static 关键字调用非静态方法?

How to call a non static method using static keyword?

我正在检查 OOPs static/non-static 概念并发现了一些奇怪的东西。

我听说静态方法的输出可以通过使用 static 关键字和 resolution operator(::) 来获得。但是在我的程序中,我使用 static 关键字获取非静态方法的值。谁能解释一下这个程序?我越来越糊涂了。

<?php
error_reporting(E_ALL);

class parentclass
{
    protected function sum()
    {
        return 145;
    }
}

class childclass extends parentclass
{
    protected function sum()
    {
        return 125;
    }
}

class grandchild extends childclass
{
    function sum()
    {
        return 100;
    }

    function __construct()
    {
        echo static::sum(); // 100 as output but how
    }
}

$obj = new grandchild(); 
?>

除此之外,如果我将 childclass 的函数 sum() 设为静态,如

class childclass extends parentclass
{
   protected static function sum()
   {
    return 125;
   }
 }

然后它也给出如下致命错误:

致命错误:无法在 class 子 class

中使非静态方法 parentclass::sum() 静态化

但是为什么我不调用那个函数。

您正在使用 static 作为 Late Static Binding。但是你听说的是

class Foo
{
  static function bar() {}
}

$baz = Foo::bar();

您可以静态调用一个函数,即使它没有声明为 static,只要您不在其中引用 $this

这就是原始代码有效的原因。

但是,您不能更改继承方法的签名。

Fatal error: Cannot make non static method parentclass::sum() static in class childclass

当您在 childclass 中声明 protected static function sum() 时,您正在更改从 parentclass 继承的方法的签名,而未明确声明 static.

最重要的是,您正在尝试使用一些 PHP 我会反对的怪癖。是的,它们有效,但这并不意味着您应该使用它们。

坚持严格的编码风格。为静态和实例使用编写单独的方法,并按预期调用它们。

我认为要更好地理解后期静态绑定,您可以编写代码的变体:

<?php
error_reporting(E_ALL);

class parentclass
{
    protected function sum()
    {
        return 145;
    }

    public function do_the_math()
    {
        printf('Static sum: %d, Self sum: %d', 
            static::sum(), 
            self::sum());
    }
}

class childclass extends parentclass
{
    protected function sum()
    {
        return 125;
    }
}

class grandchild extends childclass
{
    function sum()
    {
        return 100;
    }
}

$obj = new grandchild(); 
$obj->do_the_math();

输出:

Static sum: 100, Self sum: 145