Jack Scandall
Jack Scandall

Reputation: 402

PHP: understanding $this - calling base class method instead of child method

Reading the PHP.net documentation I stumbled upon a problem that twisted the way I understand $this:

class C {
    public function speak_child() {
        //echo get_class($this);//D
        echo $this->f();//calls method of C class... why?!
    }

    private function f() {
        echo "C";
    }
}

class D extends C {
    public function speak_parent() {
        echo $this->f();
    }
    public function f() {
        echo "D";
    }
}

$d= new D();
$d->speak_parent();
$d->speak_child();

Since $this is representation of the instance of D class, I would expect the output:

DD

But, the actual output is:

DC

Why $this->f() will rather access base class method, than child class method? The situation changes when we change C->f to be public.

Upvotes: 2

Views: 934

Answers (2)

El_Vanja
El_Vanja

Reputation: 3993

Why $this->f() will rather access base class method, than child class method?

That's the design. And it makes sense when you think about it. In layman's terms, inheritance is all about properties and methods that are common. So the most logical thing is to start at the top of the chain - the level with the most common methods/properties (most as a superlative, not as a quantifier). Here's the simplified logic:

  • Does the parent class have the method?
  • If not, check the child class. If yes, check visibility.
  • If child can override the method, check if it has an overridden method.
  • If not, run parent. If yes, run child.
  • If child cannot override, run the parent.

The last point is key for your example. The parent class does not expect the child class to have an implementation of the same method. When you declare a method in the parent class as private, you're saying that the child class has no business dealing with this. So it makes no sense to create a method of the same name inside the child class. If the child has the need to use it, then that method needs to be made either public or protected, based on the use case.

$this always represents the instance of the class you constructed. But, you must remember that a child class represents both an instance of itself and an instance of the parent. Usage of methods and properties will depend on the logic described above.

Upvotes: 1

Van Tho
Van Tho

Reputation: 633

Because function f of class C is private, it cannot be overwrite by child class, the child class won't see it. So when you declare a function f in child class, it's a new function, not extended from parent class.

You can also extend function f if you declare it as protected in parent class.

Arcoding to the official document here

Members declared as private may only be accessed by the class that defines the member.

Upvotes: 1

Related Questions