<?php
class Bar
{
public function test() {
$this->testPrivate();
$this->testPublic();
}
public function testPublic() {
echo "Bar::testPublic\n";
}
private function testPrivate() {
echo "Bar::testPrivate\n";
}
}
class Foo extends Bar
{
public function testPublic() {
echo "Foo::testPublic\n";
}
private function testPrivate() {
echo "Foo::testPrivate\n";
}
}
$myFoo = new Foo();
$myFoo->test(); // Bar::testPrivate
// Foo::testPublic
Паблик он берет из дочернего класса, А приватный из своего. Что совсем не логично. Ведь он не может достать ПриватныйМетод. Ведь он не наследуется.
public function test() {
$this->testPrivate();//По сути в объекте нашего класса его нет, он же не наследуется, т.к. Приватное
$this->testPublic();
}
И это первый вопрос, каким образом это работает, что вызывается метод, который не наследуется, в других языках я вроде такого не встречал.
ВТОРОЕ.Я думал что т.к. я наследовал класс, то теперь типо test есть в моем наследованном классе, и он может работать со всеми моими методами. Но вызвать Приватный метод в дочернем классе он не может.
Класс Foo
расширил класс Bar
, унаследовал метод test()
и перегрузил метод testPrivate()
. Но т.к. данный метод private
, он (перегруженный testPrivate()
) вне области видимости класса Bar
. По этой причине класс Bar
вызывает тот testPrivate()
, который видит - свой.
upd:
Вы не наследуете test()
в абсолютном понимании этого термина. Слово extends переводится как РАСШИРЯЕТ, это оно и означает. Класс Foo
расширил функционал класса Bar
. $myFoo
будет определятся php
и как экземпляр класса Bar
$myFoo = new Foo();
echo ($myFoo instanceof Foo); //output = 1
echo ($myFoo instanceof Bar); //output = 1
upd2:
До тех пор пока эти методы не будут переопределены, они будут сохранять свою исходную функциональность. (https://www.php.net/manual/ru/language.oop5.inheritance.php)
Методы с модификатором доступа private
не перегружаются (не переопределяются).
upd3:
... Я спрашиваю почему они оказывается в объекте дочернего класса, приватные методы и свойства ?
Они там не оказываются. Спросите себя, почему test()
вообще был вызван? Потому, что интерпретатор сперва проверил родительский класс Bar
, нашёл там tect()
, далее проверил дочерний Foo
, не нашёл там перегруженный tect()
и начал интерпретировать test()
в Bar
. Далее, перейдя на $this->testPrivate();
он, по той же схеме, нашёл данный метод в Bar
, не нашёл (нашёл, но модификатором ему запрещено его выполнять, ведь он в данный момент в классе Bar
) private testPrivate()
и выполнил найденный.
Хорошая статья вот
upd4:
Касаемо приватных свойств.
class Bar
{
private $a = 'some';
}
class Foo extends Bar
{}
var_dump(new Foo);
// Foo Object
// (
// [a:Bar:private] => some
// )
[a:Bar:private] => some
не означает, что класс Bar
содержит данное свойство. Это лишь указатель на то, что где-то в цепочке родителей класса Foo
(в данном случае в Bar
) есть приватное свойство. Собственно из записи дампа всё и так ясно.
[имя:
a:класс:
Bar:модификатор доступа:
private]
В памяти компьютера под класс создаётся структура zend_class_entry
, среди полей которой есть parent
- указатель (ссылка) на родителей данного класса. По этой ссылке в var_dump
класса Foo
попадает private $a
класса Bar
.
Очень в общем, но суть, думаю, ясна.
Документация по PHP:
Например, при расширении класса дочерний класс наследует все общедоступные и защищенные методы из родительского класса. До тех пор пока эти методы не будут переопределены, они будут сохранять свою исходную функциональность.
Определите методы testPrivate()
не private
, а protected
.
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Есть проект на PHP, посоветуйте способы как удобно и красиво заливать изменения на продакшнЖелательно хранить несколько последних версий...
В языке C# есть перечисления (enum)Удобная вещь, чтобы не заводить магические числа/строки/значения
Запускаю из консоли php файл на выполнение, но никакого результата нетОшибку не выдаёт никакую, но и код не выполняется
Нужно вывести значения из таблицы в один div блок, где две заметки (картинка, название, краткое описание и тд