简体   繁体   English

“self”如何在继承的类中完全正常工作?

[英]How does 'self' exactly work in inherited classes?

According to php, class::self always points to the class itself, but as I wrote down these codes, something strange happens: 根据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();

I thought the output would have been: 我认为输出会是:

foo() from C_foo
foo() from C_bar

But in fact: 但实际上:

foo() from C_foo
foo() from C_foo

It means that the self in parent class does NOT exactly inherit into the child, it works more like to this: 这意味着父类中的self并不完全继承到子级,它更像是这样:

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

Is that a feature from php or is it a bug? 这是PHP的一个功能还是一个bug? Or is it mean to be like this? 或者是这样的意思?

Otherwise, such thing is occurred as I tried to tell a class create objects from itself, the code is something like this: 否则,当我试图告诉一个类从它自己创建对象时会发生这样的事情,代码是这样的:

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

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

class Something extends Models {...}

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

Maybe someone would ask, "why don't you set a variable with the value of class , and use the variable as the __construction function?" 也许有人会问,“为什么不用的值设置变量,并将变量用作__construction函数?”

Like this: 像这样:

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

In fact I did that, and got a even more weird result: 事实上,我做到了这一点,并得到了一个更奇怪的结果:

It works only when the class does not have any property or function but find() , or an error telling me a variable shows off where a function sould exist would jump out. 它只有在类没有任何属性或函数但是find()时才会起作用,或者一个错误告诉我一个变量显示函数存在的位置会跳出来。

It sounds like you're describing the PHP feature known as 'late static binding'. 听起来你正在描述被称为“后期静态绑定”的PHP功能。

PHP provides two syntaxes: self:: and static:: . PHP提供了两种语法: self::static::

static was introduced in PHP 5.3 because a lot of people expected self to work the you're describing. static是在PHP 5.3中引入的,因为很多人都希望self能够按照你所描述的方式工作。

See the PHP manual for more: http://php.net/manual/en/language.oop5.late-static-bindings.php 有关更多信息,请参阅PHP手册: http//php.net/manual/en/language.oop5.late-static-bindings.php

You can also use the syntax new self() or new static() to create new instances: 您还可以使用语法new self()new static()来创建新实例:

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

This is because the class which receives the methods of the parent is of that class. 这是因为接收父类方法的类属于该类。 So: 所以:

$bar is Bar, therefore self:: refers to Bar, not to Foo. $ bar是Bar,因此self ::指的是Bar,而不是Foo。 Even though that method is from Foo. 即使那个方法来自Foo。

This may be different from Java, but it probably indicates how PHP is doing inheritance internally. 这可能与Java不同,但它可能表明PHP如何在内部进行继承。

In PHP, classes are not object. 在PHP中,类不是对象。 Because of that, there is no inheritance of static methods (actually, they are similar to global functions). 因此,没有静态方法的继承(实际上,它们与全局函数类似)。

So, when C_foo says self, it always means C_foo (even if you called a method from C_bar). 所以,当C_foo说self时,它总是意味着C_foo(即使你从C_bar调用了一个方法)。

If you want create instances from an abstract class method, you should try the Factory pattern. 如果要从抽象类方法创建实例,则应尝试使用Factory模式。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM