За последние 24 часа нас посетили 20912 программистов и 1107 роботов. Сейчас ищут 422 программиста ...

ООП. наследование private свойств

Тема в разделе "Прочие вопросы по PHP", создана пользователем runcore, 15 янв 2015.

  1. runcore

    runcore Старожил

    С нами с:
    12 окт 2012
    Сообщения:
    3.625
    Симпатии:
    158
    В документации есть такие строки:
    Хотя тут речь только про методы, обычно свойства ведут себя аналогично, если не оговорено иное. Так вот, получается что дочерний класс не должен наследовать приватные свойства и методы родителя.

    На самом деле, приватные свойства и методы вполне себе наследуются.
    Код (PHP):
    1. class A {
    2.     private $a = 1;
    3. }
    4.  
    5. class B extends A {}
    6.  
    7. print_r( new A ); // A Object ( [a:A:private] => 1 )
    8. print_r( new B ); // B Object ( [a:A:private] => 1 )    
    видно, что контекст обявления свойства родительский. но по сути, можно написать методы и использовать значение приватного свойства в методах наследников.

    Мне это поведение показалось несколько неочевидным.
    Как считаете, это нормально? или все таки недоработка движка пхп?
     
  2. Ganzal

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

    С нами с:
    15 мар 2007
    Сообщения:
    9.902
    Симпатии:
    969
    я вот сейчас прям ого. никогда не пробовал но был уверен что не должны попадать приватные куски в наследуемый класс. офигеть. косяк конечно.
     
  3. runcore

    runcore Старожил

    С нами с:
    12 окт 2012
    Сообщения:
    3.625
    Симпатии:
    158
    я вот тоже был удивлен. порылся в доках, четкого описания такого поведения не нашел(может просто не по глазам)
     
  4. igordata

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

    С нами с:
    18 мар 2010
    Сообщения:
    32.410
    Симпатии:
    1.768
    они не видны? но видимо кто-то посчитал, что раз не видны, то это ещё не значит, что они не востребованы во внутренней механике...
     
  5. Ganzal

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

    С нами с:
    15 мар 2007
    Сообщения:
    9.902
    Симпатии:
    969
    насколько я помню - приватные элементы при наследовании должны как бы стираться и потомок как бы про них ничего не знает. на то они и приватные. а защищенные - копируются. как и публичные. но там как мы знаем немного другая логика внешнего доступа.
     
  6. Fell-x27

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

    С нами с:
    25 июл 2013
    Сообщения:
    12.155
    Симпатии:
    1.769
    Адрес:
    :сердА
    Это пхп, народ, тут ООП еще совсем молодое. Можно сказать, с дерева неделю как слезло.
    Вы еще вспомните, что через объект класса можно обращаться к методам его класса вне контекста объекта как к статике :)
     
  7. runcore

    runcore Старожил

    С нами с:
    12 окт 2012
    Сообщения:
    3.625
    Симпатии:
    158
    наследник как раз его видит. если в наследнике не создать свойство с таким же именем(по сути переопределить его) то можно его юзать(с трудом но можно) со значением из предка. получается что это не чистый private а некий урезанный protected
     
  8. Fell-x27

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

    С нами с:
    25 июл 2013
    Сообщения:
    12.155
    Симпатии:
    1.769
    Адрес:
    :сердА
    У меня phpStorm в интеллисенс не прописывает приватные методы, пытаясь вести себя адекватно, но да, если прописать через игнорирование ворнингов IDE, все работает.
     
  9. runcore

    runcore Старожил

    С нами с:
    12 окт 2012
    Сообщения:
    3.625
    Симпатии:
    158
    а есть еще такая фигня.
    хотябы описано четко в доках.
    но возникает некое противоречие, ибо я представлял себе что так работать не должно.

    Добавлено спустя 2 минуты 8 секунд:
    тоесть если у нас есть два разных объекта одного класса, они могут копашиться в private свойствах друг друга. извращенцы)
     
  10. Fell-x27

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

    С нами с:
    25 июл 2013
    Сообщения:
    12.155
    Симпатии:
    1.769
    Адрес:
    :сердА
    Это, с одной стороны, интересно.
    С другой же - очень похоже на баг, выдаваемый за фичу. Крааайне похоже. Мол, при доступе к private проверяется тупо принадлежность к классу, а не однозначность между вызывающим и $this.
     
  11. runcore

    runcore Старожил

    С нами с:
    12 окт 2012
    Сообщения:
    3.625
    Симпатии:
    158
    незнаю специально это сделали или просто не смогли по другому. но мне это ненравится. ибо приватность я представлял по другому.
    в частности программируя на других языках.
     
  12. mkramer

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

    С нами с:
    20 июн 2012
    Сообщения:
    8.548
    Симпатии:
    1.754
    Так даже в C++, это нормально

    Ну интересно, а должны же методы базового класса, которые используют эти приватные поля, как-то работать в производном. Если там метод рассчитывает, что приватное поле есть, а его вдруг нету, то будет ошибка. В документации некорректно сформулировали этот момент. Наследуется всё, а вот доступ методы производного класса могут получить только к public и protected полям/методам. А методы базового класса, унаследованные производным, имеют доступ к приватным полям базового класса внутри объекта производного класса, и физически приватные поля базового класса присутствуют, конечно, в экземплярах производного. Так что в приведённом runcore примере php отработал корректно.
     
  13. runcore

    runcore Старожил

    С нами с:
    12 окт 2012
    Сообщения:
    3.625
    Симпатии:
    158
    зато буду знать теперь)
     
  14. Fell-x27

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

    С нами с:
    25 июл 2013
    Сообщения:
    12.155
    Симпатии:
    1.769
    Адрес:
    :сердА
    О_о
    Сурьезно? Просто ни разу мысль не появлялась даже, чтобы нечто подобное делать.
    Однакож)
     
  15. mkramer

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

    С нами с:
    20 июн 2012
    Сообщения:
    8.548
    Симпатии:
    1.754
    А как вы иначе представляете себе в С++ работу конструктора копирования, или перегруженного оператора присваивания? Да и вообще любого перегруженного оператора...
     
  16. [vs]

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

    С нами с:
    27 сен 2007
    Сообщения:
    10.553
    Симпатии:
    631
    как?
    Код (Text):
    1. class A {
    2.     private $a = 1;
    3. }
    4.  
    5. class B extends A {
    6.    
    7.     function get1() {
    8.         return $this->a;
    9.     }
    10.    
    11.     function get2() {
    12.         return parent::$a;
    13.     }
    14.  
    15. }
    16.  
    17. $b = new B;
    18. var_dump($b->get1()); // NULL
    19. var_dump($b->get2()); // Fatal Error: Cannot access private property A::$a
     
  17. Fell-x27

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

    С нами с:
    25 июл 2013
    Сообщения:
    12.155
    Симпатии:
    1.769
    Адрес:
    :сердА
    Ой да брось, не первый год "знакомы", к чему такая официальщина.
    Для объектов? Через реализацию iClone-интерфейса же.
    Эм...а они тут при чем? В любом перегруженном операторе я сам определяю, что куда и как. Если я перегружаю, скажем, + на сложение двух объектов, то я, руками определяю порядок получения данных и их обработку с последующим формированием результата.
    С присваиванием та же тема.
     
  18. mkramer

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

    С нами с:
    20 июн 2012
    Сообщения:
    8.548
    Симпатии:
    1.754
    Fell-x27, ну я давно, честно говоря, не писал на C++, когда я в нём писал, интерфейсов не было. А по поводу перегрузки операций - ну вы же будете сравнивать (копировать, "складывать") данные, содержащиеся в приватных членах данных, не? Поэтому вам надо, чтоб метод класса имел доступ к приватным членам другого экземпляра того же самого класса.
     
  19. Fell-x27

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

    С нами с:
    25 июл 2013
    Сообщения:
    12.155
    Симпатии:
    1.769
    Адрес:
    :сердА
    не обязательно, на самом деле. Но да.
    Зачем? Если я перегружаю оператор, обращающийся к, скажем, двум операндам, я имею доступ к обоим операндам. Каждый из которых имеет доступ в свои приватные поля. Никто не мешает мне спросить их напрямую у объектов, входящих в выражение.

    НО, если они приватные, и, при этом, не имеющие полей, которые их инкапсулируют, значит, по хорошему, они не рассчитаны на то, чтобы их было видно извне. Вообще. То есть, это некие данные, которые нужны самому объекту. И которые априори не нужно тащить наружу, не нужно складывать, вычитать и переприсваивать с чем-то извне. По этому, даже имея возможность обращаться к ним из самого объекта, не нужно так делать. Если встала нужда оперировать приватными данными - это плохой симптом.
     
  20. mkramer

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

    С нами с:
    20 июн 2012
    Сообщения:
    8.548
    Симпатии:
    1.754
    Ну операции можно перегружать в С++ двумя путями: как отдельную функцию, или как функцию-член. Я всегда работал со вторым путём. Хотя, ладно, совсем мы с вами в офтоп ушли.
     
  21. Fell-x27

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

    С нами с:
    25 июл 2013
    Сообщения:
    12.155
    Симпатии:
    1.769
    Адрес:
    :сердА
    Да что ж ты такой официальный-то. Я не так стар и пафосен, чтобы ко мне на "вы" обращаться :)
    З.Ы. Всегда перегружал через отдельную функцию перегрузки, да :)

    Добавлено спустя 1 минуту 20 секунд:
    Чтобы не было оффтопа, давайте пообсуждаем перегрузку операторов в пхп.
     
  22. mkramer

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

    С нами с:
    20 июн 2012
    Сообщения:
    8.548
    Симпатии:
    1.754
    А что, она есть? Просвети :))) ArrayAcсess - это не совсем то, насколько я понимаю.
     
  23. igordata

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

    С нами с:
    18 мар 2010
    Сообщения:
    32.410
    Симпатии:
    1.768
    нафига она нужна при нестрогой типизации и ассоциативных массивах? вот именованные параметры - было бы удобняк.
     
  24. Fell-x27

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

    С нами с:
    25 июл 2013
    Сообщения:
    12.155
    Симпатии:
    1.769
    Адрес:
    :сердА
    НЕТ.
    АХАХАХАХАХАХАХА.

    Добавлено спустя 35 секунд:
    мы сейчас о перегрузке операторов, а не методов. Это мальца другой феншуй.
     
  25. Ganzal

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

    С нами с:
    15 мар 2007
    Сообщения:
    9.902
    Симпатии:
    969
    кстати функции будут возвращать типизованное значение. скоро. вдруг...