Я привык помещать метод как protected
в свои классы PHP. Но, играя с private
, я начинаю сомневаться.
Я знаю, что это может быть дубликат, но я не могу найти ясности в SO-ответах, которые я прочитал. Проверены документация и SO ответы, но все же мои тесты не соответствуют тому, что там говорится (см. ниже) .
В частности, не часто объясняется своего рода «запутывание» между методами public
и private
при расширении класса одного и того же типа в контексте PHP.
Например:
<?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
При запуске вот такой результат:
test test overridden-public test test
Суть в том, что я ожидал, что метод private
унаследован, но недоступен для дочерних классов; следовательно:
- Я не смогу изменить видимость
ab()
наpublic
- с переопределением
ab()
вB
я ожидал бы, чтоtest()
вызоветab()
на$this
как экземплярB
и напечатает "overridden-public" accessprivate()
с$a2
по$a
нормально, потому что они одного классаaccessprivate()
с$b
по$a
НЕ должно быть хорошо, потому что это разные классы (родительский и дочерний)
Итак, вопросы:
- Почему я ошибаюсь? Что я неправильно понимаю?
- Является ли эта модель видимости такой же на других языках или PHP делает это по-другому? И в таком случае соответствуют ли мои ожидания модели видимости какого-то другого языка?
public function accessprivate($obj) { $obj->ab(); }
, вы получите ожидаемую ошибку. Я предполагаю, что контекст php по-прежнему привязан к A, когда вы делаете$obj->ab()
, но я понятия не имею, почему. - person k0pernikus   schedule 02.08.2019public function ab()
наB
ничего не отменяет. Он создает совершенно новый метод наB
. (Для других языков требуется ключевое словоoverride
. В Php его нет, поэтому это может сбивать с толку.) Таким образом, наличиеA::ab()
private запрещает родительский вызов вB
, поэтому вы не можете выполнятьparent::ab()
вB
из-за частного доступа. - person k0pernikus   schedule 02.08.2019