keeper_evil
23.05.2013 - 14:22
На днях столкнулся с описанной ниже проблемой. Моему удивлению и удивлению моих коллег не было предела. :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
23.05.2013 - 14:30
keeper_evilпотому что в $a1 = new A1(); ты создаешь экземпляр класса A1 extends которого A, и вызываешь метод testA() из класса А который передался А1
было бы очень странно если бы такое нельзя было провернуть...
_____________
Ex3m.com.ua — Активный образ жизни
Игорь_Vasinsky
23.05.2013 - 14:35
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
23.05.2013 - 14:48
Цитата (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 создали - в нём родительский метод |
Здесь две ветки наследования с общим родителем. По сути мы залезаем из одной ветки в другую. Вызов защищенного метода предка в наследнике - это нормально, но не нормально когда такой вызов проходит для наследника из другой ветки (ИМХО).
dron4ik
Игорь_Vasinsky
т.е. вас не удивляет что вызывается protected метод класса A1, при этом A2 не является наследником A1.
AlmazDelDiablo
23.05.2013 - 14:52
protected — метод доступ для самого класса и всех его наследников, но не доступен из-вне.
private — метод доступен только для самого класса.
Это не у PHP проблемы, а у вас и ваших коллег пробелы в знаниях и умении гуглить. Извините.
_____________
Блог |
VK |
GitHub |
Twitch
Игорь_Vasinsky
23.05.2013 - 14:55
$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
23.05.2013 - 14:59
AlmazDelDiabloКакой тонкий троллинг

, обратите внимание на мой предыдущий пост (он исправлен).
dron4ik
23.05.2013 - 15:01
Guestа что там может смущать?
protected function testA() является открытым для дочерних классов... и его вызов полностью оправдан... как подметил AlmazDelDiablo
_____________
Ex3m.com.ua — Активный образ жизни
Игорь_Vasinsky
23.05.2013 - 15:03
наследник унаследовал у наследника. и тоже ничего)
т.к.
Цитата |
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
23.05.2013 - 15:03
Цитата |
т.е. вас не удивляет что вызывается 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
23.05.2013 - 15:06
Фишка в том что testA определен в классе A.
И обращаемся мы к нему из подкласса класса A.
На то они и родственные объекты, так во всяком случае задумано в php.
Чтобы такое запретить надо использовать private.
_____________
There never was a struggle in the soul of a good man that was not hard
keeper_evil
23.05.2013 - 15:09
Цитата (Игорь_Vasinsky @ 23.05.2013 - 14:55) |
$a1 = new A1(); - наследник класса A $a1->testA(); - защищённый унаследован наследником класса А |
Да, но...
Во-первых, А2 - наследник класса А, а не А1.
Во-вторых, $a1->testA() мы вызываем внутри А2, а не внутри А1.
Т.е. все бы было норм, если либо А2 наследовался от А1, либо $a1->testA() вызывался в А1.
Но почему же и без этих "либо" все работает?
dron4ik
Читаем внимательно
Цитата (AlmazDelDiablo @ 23.05.2013 - 14:52) |
protected — метод доступ для самого класса и всех его наследников, но не доступен из-вне. |
A2 не является наследником класса A1, но при этом protected метод из A1 доступен для A2
Игорь_Vasinsky
23.05.2013 - 15:12
ещё раз.
защищённый метод вызван у родителя.
$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
Быстрый ответ:
Powered by dgreen
Здесь расположена полная версия этой страницы.