[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: Странный аспект наследования в PHP
Страницы: 1, 2, 3, 4
keeper_evil
На днях столкнулся с описанной ниже проблемой. Моему удивлению и удивлению моих коллег не было предела. :blink:

Суть в том, что почему-то в PHP в методе класса-наследника (А2), наследуемого от класса-родителя (А), можно вызвать защищенный метод экземпляра класса-наследника (А1), наследуемого от того же класса-родителя (А), что и класс-наследник (А2) (Код ниже).

Прокомментируйте этот аспект, пожалуйста. Входит ли он в концепцию наследования или нет?


class A
{
protected function testA()
{

}
}


class A1 extends A
{

}


class A2 extends A
{
public function testA2()
{
$a1 = new A1();
$a1->testA(); // Почему так можно сделать?
}
}



П.С. Кстать, на С# такое сделать нельзя. Проверили.
dron4ik
keeper_evil
потому что в $a1 = new A1(); ты создаешь экземпляр класса A1 extends которого A, и вызываешь метод testA() из класса А который передался А1

было бы очень странно если бы такое нельзя было провернуть...

_____________
Ex3m.com.ua — Активный образ жизни
Игорь_Vasinsky
testA() из класса A доступен в A1 т.к. class A1 extends A
и что вас удивило - экземпляр класса А1 создали - в нём родительский метод

_____________
HTML, CSS (Bootstrap), JS(JQuery, ExtJS), PHP, MySQL, MSSql, Posgres, (TSql, BI OLAP, MDX), Mongo, Git, SVN, CodeIgnater, Symfony, Yii 2, JiRA, Redmine, Bitbucket, Composer, Rabbit MQ, Amazon (SQS, S3, Transcribe), Docker
keeper_evil
Цитата (dron4ik @ 23.05.2013 - 14:30)
keeper_evil
потому что в $a1 = new A1(); ты создаешь экземпляр класса A1 extends которого A, и вызываешь метод testA() из класса А который передался А1

было бы очень странно если бы такое нельзя было провернуть...

Цитата (Игорь_Vasinsky @ 23.05.2013 - 14:35)
testA() из класса A доступен в A1 т.к. class A1 extends A
и что вас удивило - экземпляр класса А1 создали - в нём родительский метод

Здесь две ветки наследования с общим родителем. По сути мы залезаем из одной ветки в другую. Вызов защищенного метода предка в наследнике - это нормально, но не нормально когда такой вызов проходит для наследника из другой ветки (ИМХО).

Guest
dron4ik
Игорь_Vasinsky
т.е. вас не удивляет что вызывается protected метод класса A1, при этом A2 не является наследником A1.
AlmazDelDiablo
protected — метод доступ для самого класса и всех его наследников, но не доступен из-вне.
private — метод доступен только для самого класса.

Это не у PHP проблемы, а у вас и ваших коллег пробелы в знаниях и умении гуглить. Извините.

_____________
Блог | VK | GitHub | Twitch
Игорь_Vasinsky
$a1 = new A1(); - наследник класса A
$a1->testA(); - защищённый унаследован наследником класса А


_____________
HTML, CSS (Bootstrap), JS(JQuery, ExtJS), PHP, MySQL, MSSql, Posgres, (TSql, BI OLAP, MDX), Mongo, Git, SVN, CodeIgnater, Symfony, Yii 2, JiRA, Redmine, Bitbucket, Composer, Rabbit MQ, Amazon (SQS, S3, Transcribe), Docker
keeper_evil
AlmazDelDiablo

Какой тонкий троллинг smile.gif, обратите внимание на мой предыдущий пост (он исправлен).
dron4ik
Guest
а что там может смущать?
protected function testA() является открытым для дочерних классов... и его вызов полностью оправдан... как подметил AlmazDelDiablo

_____________
Ex3m.com.ua — Активный образ жизни
Игорь_Vasinsky
наследник унаследовал у наследника. и тоже ничего)
т.к.
Цитата
protected — метод доступ для самого класса и всех его наследников, но не доступен из-вне.


class A{
protected function A(){
return 'Wow';
}
}


class A1 extends A{

}


class A2 extends A1{
public function A2(){
$a1 = new A;
return $a1->A();
}
}


$A2 = new A2;
echo $A2->A2();
?>


_____________
HTML, CSS (Bootstrap), JS(JQuery, ExtJS), PHP, MySQL, MSSql, Posgres, (TSql, BI OLAP, MDX), Mongo, Git, SVN, CodeIgnater, Symfony, Yii 2, JiRA, Redmine, Bitbucket, Composer, Rabbit MQ, Amazon (SQS, S3, Transcribe), Docker
Игорь_Vasinsky
Цитата
т.е. вас не удивляет что вызывается protected метод класса A1, при этом A2 не является наследником A1.


так ты метод то дёргал не из A2, а из

$a1 = new A1();


_____________
HTML, CSS (Bootstrap), JS(JQuery, ExtJS), PHP, MySQL, MSSql, Posgres, (TSql, BI OLAP, MDX), Mongo, Git, SVN, CodeIgnater, Symfony, Yii 2, JiRA, Redmine, Bitbucket, Composer, Rabbit MQ, Amazon (SQS, S3, Transcribe), Docker
Michael
Фишка в том что testA определен в классе A.
И обращаемся мы к нему из подкласса класса A.
На то они и родственные объекты, так во всяком случае задумано в php.
Чтобы такое запретить надо использовать private.

_____________
There never was a struggle in the soul of a good man that was not hard
keeper_evil
Цитата (Игорь_Vasinsky @ 23.05.2013 - 14:55)
$a1 = new A1(); - наследник класса A
$a1->testA(); - защищённый унаследован наследником класса А

Да, но...
Во-первых, А2 - наследник класса А, а не А1.
Во-вторых, $a1->testA() мы вызываем внутри А2, а не внутри А1.

Т.е. все бы было норм, если либо А2 наследовался от А1, либо $a1->testA() вызывался в А1.

Но почему же и без этих "либо" все работает?
Guest
dron4ik
Читаем внимательно
Цитата (AlmazDelDiablo @ 23.05.2013 - 14:52)
protected — метод доступ для самого класса и всех его наследников, но не доступен из-вне.

A2 не является наследником класса A1, но при этом protected метод из A1 доступен для A2
Игорь_Vasinsky
ещё раз.

защищённый метод вызван у родителя.


$a1 = new A1(); - extends A
$a1->testA(); - унаследованный родительский метод в класса A1

$a1 - это экземпляр класса A1 - он может видеть protected методы у родителя


Тебя сбило то что ты в левом классе создал экземпляр второго класса и из него выдернул метод первого класса.

ты хоть в пятом классе работай - ты работаешь с экземпляром 2го класса

_____________
HTML, CSS (Bootstrap), JS(JQuery, ExtJS), PHP, MySQL, MSSql, Posgres, (TSql, BI OLAP, MDX), Mongo, Git, SVN, CodeIgnater, Symfony, Yii 2, JiRA, Redmine, Bitbucket, Composer, Rabbit MQ, Amazon (SQS, S3, Transcribe), Docker
Быстрый ответ:

 Графические смайлики |  Показывать подпись
Здесь расположена полная версия этой страницы.
Invision Power Board © 2001-2024 Invision Power Services, Inc.