【问题标题】:PHP: Overwriting of static methods does not work as expectedPHP:覆盖静态方法不能按预期工作
【发布时间】:2013-09-21 19:18:30
【问题描述】:

我有两个 php 类:TestUK 和 TestFR,它们扩展了 TestUK。

这两个类都用于生成对两个不同域的请求。但是继承出了点问题,我不明白为什么。

我有一个名为“get_domain”的方法,它被覆盖以获取实际应该使用的域。如果我直接通过TestFR::get_domain() 调用它,我会收到预期的结果。但是,如果我调用一个未被 TestFR 覆盖但使用 self::get_domain() 的方法,我会收到错误的域。

如果我只是将方法 do_stuff 从 TestUK 复制并粘贴到 TestFR,那么我会得到预期的结果。但复制粘贴相同 (!) 代码正是我试图避免的。

这是什么原因?我对 PHP 中的类继承没有太多经验,但我希望这可以毫无问题地工作。还是我的方法完全有缺陷?

<?php
class TestUK {

    const DOMAIN_UK = 'http://www.domain.co.uk';
    const DOMAIN_FR = 'http://www.domain.fr';

    static function get_domain(){
        return self::DOMAIN_UK;
    }

    static function do_stuff(){
        echo self::get_domain();
    }

}

class TestFR extends TestUK {

    static function get_domain(){
        return self::DOMAIN_FR;
    }

}

// Works as intended:
// Expected and actual output: http://www.domain.fr
echo TestFR::get_domain();

// Does NOT work as intendes:
// Expected Output: http://www.domain.fr
// Actual Output:   http://www.domain.co.uk
TestFR::do_stuff();
?>

【问题讨论】:

    标签: php class inheritance static


    【解决方案1】:

    这是因为关键字self 指的是它出现的类,而不是调用该方法的类。对于后一种功能,您必须使用 late static bindingstatic 关键字:

    static function do_stuff(){
        echo static::get_domain();
    }
    

    也就是说,这段代码闻起来很糟糕。为什么一切都是static 而不仅仅是一个实例方法?为什么TestFR 扩展TestUK 而不是都扩展抽象基类Test

    将所有内容都转换为非静态方法会好多了,而且作为奖励,您的问题会立即消失。

    【讨论】:

    • 现在已将其转换为非静态。我意识到这是更好的方法,它是一些原本不打算使用多个域的旧代码。两种解决方案(使用“静态”并将类转换为非静态)都有效。这真的让我很烦,到底是什么导致了这里的问题。
    【解决方案2】:

    这样称呼它(如果您使用的是 php >= 5.3

    static::get_domain();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-06-21
      • 1970-01-01
      • 2020-05-02
      • 1970-01-01
      • 2018-07-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多