I'm used to put method as protected
in my PHP classes. But playing with private
I'm starting to have doubts.
I know that it might be a duplicate but I can't find clarity from the SO-answers I've read. Checked the documentation and SO answers but still my tests are incoherent with what is being said there (see below).
Especially is not often explained the kind of "tangling" among public
and private
method, when extending the same type class, in the context of PHP.
For example:
<?php
class A
{
private function ab() { echo 'test'.PHP_EOL; }
public function test() { $this->ab(); }
public function accessprivate($obj) { $obj->ab(); }
}
class B extends A
{
public function ab() { echo 'overridden-public'.PHP_EOL; } // expect notice overriding private parent method
}
$a = new A;
$a2 = new A;
$b = new B;
$a->test(); // expect 'test'
$b->test(); // expect access to B::ab() and print 'overridden-public'
$b->ab(); // expect access to B::ab() and print 'overridden-public'
$a2->accessprivate($a); // expect 'test' since is the same class
$b->accessprivate($a); // expect cannotaccess private of A from class B
When running this is the result:
test test overridden-public test test
The main point is that I expected that a private
method is inherited but not accessible to child classes; hence:
- I shouldn't be able to change the visibility of
ab()
topublic
- with the override of
ab()
inB
I would expecttest()
to callab()
on$this
asB
instance, and get printed "overridden-public" accessprivate()
from$a2
on$a
is fine because they are the same classaccessprivate()
from$b
on$a
should NOT be fine because they are different classes (parent & child)
So the questions are:
- Why am I wrong? What am I misunderstanding?
- Is this visibility model the same on other languages or PHP is doing it differently? And in that case, are my expectation fitting more the visibility model of some other language?