简体   繁体   中英

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:

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:

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

Is that a feature from php or is it a 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?"

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.

It sounds like you're describing the PHP feature known as 'late static binding'.

PHP provides two syntaxes: self:: and static:: .

static was introduced in PHP 5.3 because a lot of people expected self to work the you're describing.

See the PHP manual for more: 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:

$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. Even though that method is from Foo.

This may be different from Java, but it probably indicates how PHP is doing inheritance internally.

In PHP, classes are not object. 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).

If you want create instances from an abstract class method, you should try the Factory pattern.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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