【问题标题】:How does 'self' exactly work in inherited classes?'self' 在继承的类中究竟是如何工作的?
【发布时间】:2018-12-24 03:03:37
【问题描述】:

根据 php,class::self 总是指向类本身,但是当我写下这些代码时,发生了一些奇怪的事情:

class C_foo{
    function foo() { return "foo() from C_foo"; }
    function bar() { echo self::foo(); }
}

class C_bar extends C_foo{
    function foo() { return "foo() from C_bar"; }
}

C_foo::bar();
C_bar::bar();

我以为输出会是:

foo() from C_foo
foo() from C_bar

但事实上:

foo() from C_foo
foo() from C_foo

这意味着父类中的 self 并没有完全继承到子类中,它更像这样:

foo() {return parent::foo();}

这是 php 的一个特性还是一个错误?还是这样的意思?

否则,当我试图告诉一个类从自己创建对象时,就会发生这种情况,代码是这样的:

class Models {
    function find($exp) {
        ...
        ...

        $temp_model = new self();
        ...
        ...
    }
}

class Something extends Models {...}

$somethings = Something::find("...");

也许有人会问,“你为什么不设置一个值为class的变量,并将该变量用作__构造函数?”

像这样:

...
...
function find($exp) {
    ...
    ...
    $class_name = __class__;
    $temp_model = new $class_name();
    ...
    ...
}
...

事实上我是这样做的,结果更奇怪:

它仅在类没有任何属性或函数但find() 时才有效,或者告诉我一个变量显示一个函数存在的位置的错误会跳出。

【问题讨论】:

    标签: php inheritance


    【解决方案1】:

    听起来您在描述称为“后期静态绑定”的 PHP 功能。

    PHP 提供了两种语法:self::static::

    static 是在 PHP 5.3 中引入的,因为很多人希望 self 能够像您所描述的那样工作。

    查看 PHP 手册了解更多信息:http://php.net/manual/en/language.oop5.late-static-bindings.php

    您还可以使用语法new self()new static() 创建新实例:

    $parent = new self();
    $child = new static();
    

    【讨论】:

    • 编辑添加语法new xxx()除了xxx::
    【解决方案2】:

    这是因为接收父类方法的类属于该类。所以:

    $bar 是 Bar,因此 self:: 指的是 Bar,而不是 Foo。即使该方法来自 Foo。

    这可能与 Java 不同,但它可能表明 PHP 在内部是如何进行继承的。

    【讨论】:

    • 我现在正在尝试更改我的代码,可能我真的需要更深入地研究这种语言,非常感谢:)
    • 是的,php 对继承的看法不同。与其说是“堆栈”,不如说是“合并”。
    【解决方案3】:

    在 PHP 中,类不是对象。因此,没有静态方法的继承(实际上,它们类似于全局函数)。

    所以,当 C_foo 说 self 时,它总是意味着 C_foo(即使你从 C_bar 调用了一个方法)。

    如果您想从抽象类方法创建实例,您应该尝试工厂模式。

    【讨论】:

    • 非常感谢,我会试试工厂模式:)
    猜你喜欢
    • 1970-01-01
    • 2023-04-01
    • 2011-06-26
    • 2021-08-15
    • 2012-06-08
    • 2011-10-11
    • 2013-07-05
    • 1970-01-01
    相关资源
    最近更新 更多