За последние 24 часа нас посетили 22736 программистов и 1040 роботов. Сейчас ищет 661 программист ...

ООП и "protected в PHP"

Тема в разделе "PHP для профи", создана пользователем Chushkin, 25 мар 2017.

  1. Chushkin

    Chushkin Активный пользователь

    С нами с:
    17 дек 2010
    Сообщения:
    1.062
    Симпатии:
    91
    Адрес:
    Мещёра, Центр, Болото N3
    В PHP есть странная особенность - видимость защищённых свойств и методов вне созданного объекта.
    Пример:
    Код (Text):
    1. class A {
    2.     protected $protected = 'Bug!';
    3. }
    4. class B extends A {
    5.     public function __construct() {
    6.         $obj = new A;
    7.         var_dump($obj->protected);
    8.     }
    9. }
    Чем руководствовались разработчики ПХП, не понятно.
    Но я считаю, что это баг, который возвели в ранг особенности. И этот баг напрягает регулярно. :(
    ...
    Может я ретроград?
    Может я что-то пропустил и за последние 10 лет видимость защищённых свойств вне объекта стало нормой?
     
    denis01 нравится это.
  2. denis01

    denis01 Суперстар
    Команда форума Модератор

    С нами с:
    9 дек 2014
    Сообщения:
    12.230
    Симпатии:
    1.715
    Адрес:
    Молдова, г.Кишинёв
    Наследование влияет на результат.

    https://secure.php.net/manual/ru/language.oop5.visibility.php#language.oop5.visibility-other-objects
     
  3. Chushkin

    Chushkin Активный пользователь

    С нами с:
    17 дек 2010
    Сообщения:
    1.062
    Симпатии:
    91
    Адрес:
    Мещёра, Центр, Болото N3
    Так и я об этом.
    А такого быть не должно, в принципе.
     
  4. denis01

    denis01 Суперстар
    Команда форума Модератор

    С нами с:
    9 дек 2014
    Сообщения:
    12.230
    Симпатии:
    1.715
    Адрес:
    Молдова, г.Кишинёв
    @Chushkin найти бы аргументы "за" такое поведение
     
  5. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    8.551
    Симпатии:
    1.754
    Из наследника - нормально. Насколько помню, и в плюсах так же. Вот приватные из наследника не видны ни в каком виде (кроме рефлексии)
     
  6. Chushkin

    Chushkin Активный пользователь

    С нами с:
    17 дек 2010
    Сообщения:
    1.062
    Симпатии:
    91
    Адрес:
    Мещёра, Центр, Болото N3
    Естественно, нормально. Так у всех.
    А из вне объекта нормально? (я именно об этом)
    --- Добавлено ---
    Например, из логики видимости. Protected д.б. видим только в объекте и его наследниках.
    Интересно, вообще есть ещё какие-нибудь языки, где защищённый доступен из вне объекта?
     
  7. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    8.551
    Симпатии:
    1.754
    Нормально, если внутри метода наследника. Приватные свойства других экземпляров того же класса тоже видно из методов (но уже не наследника). Тут инкапсуляция не нарушается, всё ОК, свой сор наружу не выносим
     
  8. askanim

    askanim Старожил

    С нами с:
    7 апр 2016
    Сообщения:
    2.201
    Симпатии:
    166
    Адрес:
    GABRIEL
    @Chushkin если ты хочешь чтоб не виделось, то существует такое свойство private
     
  9. Fell-x27

    Fell-x27 Суперстар
    Команда форума Модератор

    С нами с:
    25 июл 2013
    Сообщения:
    12.155
    Симпатии:
    1.769
    Адрес:
    :сердА
    Он не о том. Он не ожидал, что экземпляр класса-предка, созданный внутри потомка, будет предоставлять потомку протектеды. Потому что по логике вещей, протектед - это когда класс-потомок наследует свойства и методы предка, к которым нет доступа извне. Но не когда эти свойства и методы видны и у экземпляров предка.
     
    Shkiper777 нравится это.
  10. Chushkin

    Chushkin Активный пользователь

    С нами с:
    17 дек 2010
    Сообщения:
    1.062
    Симпатии:
    91
    Адрес:
    Мещёра, Центр, Болото N3
    Не то, что не ожидал, - я знаю про эту особенность давно. Просто это неправильно, по логике ООП. Долго мучался и в конце концов решил выяснить, что думают профи по этому поводу.
     
  11. artoodetoo

    artoodetoo Суперстар
    Команда форума Модератор

    С нами с:
    11 июн 2010
    Сообщения:
    11.072
    Симпатии:
    1.236
    Адрес:
    там-сям
    Подозреваю, что так исторически сложилось: сначала ошиблись, потом решили что это не критично, а по другому будет тормозить сильнее.
     
  12. runcore

    runcore Старожил

    С нами с:
    12 окт 2012
    Сообщения:
    3.625
    Симпатии:
    158
    Они руководствовались здравым смыслом и теорией ООП, а именно (Protected (or class-protected) allows the class itself and all its subclasses to access the member).
    То что потомок может наследовать(переопределять по сути) протектед свойства - это одно, а область видимости(потомок видит и обращается к протектед или паблик свойству предка) это несколько другое.
    Где тут баг? Где написано что должно быть подругому?

    Это всегда было нормой. Просто видимо ты изначально неправильно понял этот момент.
    Такое поведение не только в Php, но и например в Java.
    Надеюсь никто не будет тут говорить что Java недостаточно или неправильно имплементирует ООП?
     
  13. artoodetoo

    artoodetoo Суперстар
    Команда форума Модератор

    С нами с:
    11 июн 2010
    Сообщения:
    11.072
    Симпатии:
    1.236
    Адрес:
    там-сям
    почитай внимательно
     
  14. [vs]

    [vs] Суперстар
    Команда форума Модератор

    С нами с:
    27 сен 2007
    Сообщения:
    10.553
    Симпатии:
    631
    @runcore я всегда понимал это как доступ наследника к свойствам родителя в рамках одной инстанции
     
  15. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    8.551
    Симпатии:
    1.754
    А как тогда писать методы, сравнивающие два состояния? Ну в C++ такие штуки используются ещё при перегрузке операторов/конструкторе копирования и т.п. В php вместо конструктора копирования clone, которая работает совсем по-другому, ОК. Но всё ещё остаются операции сравнения. Теоретически, может быть поле, которое светить геттером нет смысла, но при сравнении с другим объектом, к примеру, хотелось бы иметь возможность получить. И с существующей системой всё в порядке: метод класса А может получить доступ к приватным и защищённым свойствам любого экземпляра класса А. А с протектед - ещё и экземпляра родителя. Не вижу здесь нарушения принципа инкапсуляции, поскольку всё это происходит внутри объектов класса a
     
    [vs] нравится это.
  16. runcore

    runcore Старожил

    С нами с:
    12 окт 2012
    Сообщения:
    3.625
    Симпатии:
    158
    это проблема. Большинство почему-то считает что это доступ в рамках инстанции, хотя нигде в документации такой оговорки нет.
    Или где-то есть?

    Что именно почитать? Это поведение наблюдается во всех ЯП со взрослым ООП.
    Потомок, в данном случае, является имплементацией двух классов. И родительского и лично своего. instanceof в помощь.
    Нельзя наследовать свойства не имея к ним доступ, а раз доступ есть, то он есть и внутри инстанции и снаружи. почему вдруг снаружи надо этот доступ ограничить? это ведь тотже самый класс, ибо наследник ТОЧНО знает, что у класса родителя есть это свойство(или метод), и что оно из себя представляет, как реализовано...
     
  17. Chushkin

    Chushkin Активный пользователь

    С нами с:
    17 дек 2010
    Сообщения:
    1.062
    Симпатии:
    91
    Адрес:
    Мещёра, Центр, Болото N3
    А при чём тут "знает"?
    Protected это видимость (т.е. доступность) свойства или метода объекта, а не знание его структуры.

    Правильный подход:
    private: доступно в объекте
    protected: доступно в объекте и его потомках
    public: доступно везде, - в объекте, в его потомках, во внешнем мире (относительно объекта)
     
  18. Fell-x27

    Fell-x27 Суперстар
    Команда форума Модератор

    С нами с:
    25 июл 2013
    Сообщения:
    12.155
    Симпатии:
    1.769
    Адрес:
    :сердА
    Наверное при том, что это все одно и то же?
     
  19. runcore

    runcore Старожил

    С нами с:
    12 окт 2012
    Сообщения:
    3.625
    Симпатии:
    158
    еще раз... сложно придумать аналогию из физического мира, в данном случае, но я попробую объяснить смысл, которым руководствовались при описании и реализации защищенных свойств(ну и методов) в ООП:
    PROTECTED это предоставление доступа не только в рамках наследования, но и в рамках прямого доступа по ссылке(это Доступность свойства ВО ВСЕЙ иерархии классов потомков). те Родитель говорит, это поле будет доступно моим наследникам ТАКЖЕ КАК И МНЕ. оно недоступно чужим, но своим без проблем, хоть в рамках наследования, хоть в рамках прямого доступа. те родитель пускает к нему всех потомком и изнутри методов и из вне. а как не пустить? это же любимые дети) как им откажешь.
     
    Fell-x27 нравится это.
  20. [vs]

    [vs] Суперстар
    Команда форума Модератор

    С нами с:
    27 сен 2007
    Сообщения:
    10.553
    Симпатии:
    631
    Niet. Из этой логики вытекает, что приватные свойства открыты всем объектам одного класса.
    PHP:
    1. class A {
    2.    
    3.     private $private;
    4.    
    5.     public function set($s) {
    6.         $this->private = $s;
    7.     }
    8.    
    9.     function bingo($o) {
    10.         echo $o->private;
    11.     }
    12. }
    13.  
    14. $o1 = new A;
    15. $o1->set('Vasya');
    16.  
    17. $o2 = new A;
    18. $o2->bingo($o1);
    [​IMG]
     
    igordata нравится это.
  21. Chushkin

    Chushkin Активный пользователь

    С нами с:
    17 дек 2010
    Сообщения:
    1.062
    Симпатии:
    91
    Адрес:
    Мещёра, Центр, Болото N3
    Ты путаешь понятия "класс" и понятие "объект".
    В твоём случае, $o1 и $o2 это разные объекты. Соответственно, свойства разные (два объекта - два свойства). И неважно, что описание (декларация) структуры объектов одна и та же.
     
  22. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    8.551
    Симпатии:
    1.754
    Во всех ОО языках, с которыми я знаком в разной степени (Object Pascal, C++, Java, PHP) методам класса А доступны приватные свойства ЛЮБОГО экземпляра класса А, не только this. Почему тебя это так смущает?
     
  23. [vs]

    [vs] Суперстар
    Команда форума Модератор

    С нами с:
    27 сен 2007
    Сообщения:
    10.553
    Симпатии:
    631
    @Chushkin че я путаю, запусти код
     
  24. Chushkin

    Chushkin Активный пользователь

    С нами с:
    17 дек 2010
    Сообщения:
    1.062
    Симпатии:
    91
    Адрес:
    Мещёра, Центр, Болото N3
    (R)
    Повторюсь ещё раз...
    Правильный подход:
    private: доступно в объекте
    Только в объекте. И нигде, кроме этого объекта, - на то он и есть "приватный".

    У разрабов ПХП другая идеология, - они оперируют классами, а не объектами, судя по этому.
    А это в корне не верно, ибо class это просто описание, декларация, "тип" (аналогично "array"), не более того.
    Я так считал, считаю и вероятно буду считать, если не переубедюсь. Поэтому и спросил "Может я ретроград?" ... и стал ожидать убедительных доводов ЗА. Пока не очень.

    п.с. Надеюсь, мы говорим об одном и том же, об ООП, а не о КОП. ;)
    п.п.с. Когда я узнал об этой "особенности" ПХП, он тут же упал на несколько процентов ближе к плинтусу в моих глазах. И вот mkramer говорит, что Object Pascal, C++, Java имеют туже хрень - и они упали. :( Куда катится мир... :(
    --- Добавлено ---
    Потому что это неправильно, по моему скромному мнению.

    п.с. И хочу переубедиться, если я неправ.
     
  25. Fell-x27

    Fell-x27 Суперстар
    Команда форума Модератор

    С нами с:
    25 июл 2013
    Сообщения:
    12.155
    Симпатии:
    1.769
    Адрес:
    :сердА
    Это не правильный подход. То, что ты так хочешь, не делает это правильным. С тем же успехом можно говорить, что правильный подход - это кушать задницей. А те, кто кушают ртом, просто не понимают цимес и заблуждаются. Грубенько вышло, но суть примерно та же.
    --- Добавлено ---
    дык ты их не читаешь, судя по всему
    --- Добавлено ---
    Это не иначе как массонский заговор. Лично против тебя.
     
    askanim нравится это.