Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Explanation of PHP class members visibility and inheritance

Tags:

php

Consider the following snippet:

Class A {

    private $a = 'foo';

    public function F() {
        return $this->a;
    }

}

Class B extends A {

    private $a = 'bar';

}

echo (new B)->F();

The result is foo. Well, it's a fait accompli that php works this way. But I wonder why. If in parent's method F() declaration I use pseudo-variable $this, it refers to object context. So when I call child inherited method F() $this variable means current instance of B with private $a = 'bar', doesn't it?

Update Thanks AbraCadaver for your reply. One circumstance is still unclear for me: if $this variable is an object of B during call of F(), how can it access parent's private member? Did I understand correctly that $this within parent's method implementation is something similar to:

  public function F(B $obj) {
    return $obj->a;
}

So interpreter checks property visibility from parent class and in case of private scope it subsitutes B $obj for A $obj

like image 698
Alex Ho Avatar asked Nov 10 '22 09:11

Alex Ho


1 Answers

From PHP: Visibility:

Members declared protected can be accessed only within the class itself and by inherited and parent classes. Members declared as private may only be accessed by the class that defines the member.

In your example, regardless of the object being of class B, class A cannot access a private property of another class.

Also, if B has a protected property, that cannot override the class A property because it is private.

Both your example and the following yield foo:

Class A {

    private $a = 'foo';

    public function F() {
        return $this->a;
    }
}

Class B extends A {

    protected $a = 'bar';

    public function F() {
        return parent::F();
    }
}    
echo (new B)->F();

However, if class A is also protected then it can be overridden by class B and class A has access to the property in class B.

Yields bar:

Class A {

    protected $a = 'foo';

    public function F() {
        return $this->a;
    }
}

Class B extends A {

    protected $a = 'bar';

    public function F() {
        return parent::F();
    }
}
echo (new B)->F();
like image 51
AbraCadaver Avatar answered Nov 14 '22 21:11

AbraCadaver