За последние 24 часа нас посетили 62144 программиста и 1783 робота. Сейчас ищут 789 программистов ...

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

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

  1. Fell-x27

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

    С нами с:
    25 июл 2013
    Сообщения:
    12.156
    Симпатии:
    1.771
    Адрес:
    :сердА
    Идиты! Откуда инфа?
     
  2. Ganzal

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

    С нами с:
    15 мар 2007
    Сообщения:
    9.893
    Симпатии:
    965
  3. runcore

    runcore Старожил

    С нами с:
    12 окт 2012
    Сообщения:
    3.625
    Симпатии:
    158
    напрямик движек не даст конечно. но можно както так.
    Код (PHP):
    1. class A {
    2.  private $a = 1;
    3.  public function get1() { return $this->a; }
    4. }
    5. class B extends A {
    6.  public function get2() { return $this->get1(); }
    7. }
    8. $b = new B;
    9. var_dump($b->get2()); // int(1)    
    грязная работа, но суть в том, что в наследнике мы получили значение приватного свойства родителя.
    понятно что тут использовали паблик метод, но я лично думал что движек заругается как-то. но оказывается можно.
     
  4. Fell-x27

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

    С нами с:
    25 июл 2013
    Сообщения:
    12.156
    Симпатии:
    1.771
    Адрес:
    :сердА
    А, ну так это не обращение к приватному полю. Тут логика никак не нарушается. Кто угодно может дернуть get1 у такого объекта и получить переменную. Это, к слову, суть инкапсулированных полей в нормальных ООП-языках, где есть адекватные геттеры и сеттеры.

    Добавлено спустя 3 минуты 21 секунду:
    Экие чудные дела творятся! Так скоро и типы аргументов объявлять попросют, чтобы был порядок, и чтобы конвертация проходила по факту вхождения в функцию, а не внутри нее, силами/костылями программера, который трижды об нее убьется.
     
  5. igordata

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

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    просили уже вроде и не раз
     
  6. runcore

    runcore Старожил

    С нами с:
    12 окт 2012
    Сообщения:
    3.625
    Симпатии:
    158
    ну так у наследника то этого свойства КАКБЫ нет. оно не описано в классе наследника. но мы его получили.
    я понимаю, что логика тут срабатывает корректно. но суть вещей нарушается. мы в наследнике получили ЗНАЧЕНИЕ свойства, которого у него НЕТ. я не говорю что это неправильно, просто не совсем очевидно, и надо иметь это в виду.
    ибо можно так забыть в наследнике указать свое приватное свойство. а все будет работать без ошибок. хотя в методах будет значение предка. такие ошибки трудно найти, если допустить.
     
  7. Fell-x27

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

    С нами с:
    25 июл 2013
    Сообщения:
    12.156
    Симпатии:
    1.771
    Адрес:
    :сердА
    Наследник унаследовал публичный метод get1, который, в данном контексте, является геттером приватного поля. Тут все ок. Обычная инкапсуляция. Именно такие вещи ничего не нарушают и не ломают и работают везде.

    Добавлено спустя 48 секунд:
    В таком разрезе да, звучит мерзковатенько. Приду домой, проверю в плюсах или шарпах. На всякий.
     
  8. Fell-x27

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

    С нами с:
    25 июл 2013
    Сообщения:
    12.156
    Симпатии:
    1.771
    Адрес:
    :сердА
    В Шарпиках все работает. Что, в принципе, логично, опять же. И да, объект-наследник может содержать в себе "лишние" данные по факту, получается.

    Добавлено спустя 4 минуты:
    Забавно, правда, раньше о таких вещах никогда не задумывался, тоже считая, что приватные свойства не наследуются. Оказалось, что наследуются, пусть неявно.
     
  9. mkramer

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

    С нами с:
    20 июн 2012
    Сообщения:
    8.600
    Симпатии:
    1.764
    Я на это смотрю, как на то, что объявляя функции и методы приватными, мы запрещаем наследникам их использовать напрямую. Но они всё равно у них есть, естественно. Поскольку, ещё раз повторюсь, должны корректно срабатывать унаследованные, но не переопределённые методы родителя.
     
  10. Fell-x27

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

    С нами с:
    25 июл 2013
    Сообщения:
    12.156
    Симпатии:
    1.771
    Адрес:
    :сердА
    Это да.
     
  11. igordata

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

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    Может это утиная типизация виновата? В шарпиках же она вроде.
     
  12. Fell-x27

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

    С нами с:
    25 июл 2013
    Сообщения:
    12.156
    Симпатии:
    1.771
    Адрес:
    :сердА
    А это тут при чем?)
    И да, в шарпиках нет утиной типизации. Если хочешь использовать объект одного класса как объект другого, при том, что они не родня ни разу, надо прямо указать им, мол (objA as objB).do(); И шарпики скажут - окей, под твою ответственность, я не буду ругаться, но если упадет, давай без выпадов в мою сторону, ок?

    Добавлено спустя 3 минуты 42 секунды:
    Скажем так, хочешь безболезненно юзать тот или иной интерфейс у указанного объекта, наследуйся от этого интерфейса. Не можешь наследоваться, юзай "as". Хоть вики и говорит, что в шарпах утиная типизация есть.

    Добавлено спустя 2 минуты 59 секунд:
    Кстати, в пхп есть такое понятие как интерфейсы и абстрактные классы?
     
  13. runcore

    runcore Старожил

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

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

    С нами с:
    25 июл 2013
    Сообщения:
    12.156
    Симпатии:
    1.771
    Адрес:
    :сердА
    А спецификация как? Просто пока не нужны были, не озадачивался. А то так-то в пхп и понятие перегрузки есть, и даже понятие инкапсулирующих полей...
     
  15. runcore

    runcore Старожил

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

    runcore Старожил

    С нами с:
    12 окт 2012
    Сообщения:
    3.625
    Симпатии:
    158
    хотя... )

    например, PHP класс не может имплементировать несколько интерфейсов содержащих одинаковые методы!

    Довольно странно, учитывая что интерфейс не содержит реализации, и по сути два интерфейса описывающих одинаковый метод ни чему ни противоречат и не создают никаких неоднозначностей.
     
  17. Fell-x27

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

    С нами с:
    25 июл 2013
    Сообщения:
    12.156
    Симпатии:
    1.771
    Адрес:
    :сердА
    Не скажи. Получается две неявные идентичные сигнатуры методов в классе. Вот прописал ты реализацию, а какую из сигнатур ты раскрыл? Определенная логика в таком поведении есть.

    Это как так называемая проблема ромбовидного наследования, которая бывает в C++, если у потомка есть два предка у которых один общий предок. В итоге в потомке финальном образуется косяк. В зависимости от настроек компилятора это либо компиль-еррор, либо неоднозначность, либо просто фаталка при запуске скомпиленного кода на попытке создания объекта.

    При наследовании от двух не родственных классов/интерфейсов шанс словить такое, конечно, стремится к нулю. Но, искуственно созданная ситуация показывает, что пыху проще не работать с таким, чем работать хоть как-то. Учитывая среднюю квалификацию пыхпышников, это ок. Крайне ок. Меньше говна будет.
     
  18. runcore

    runcore Старожил

    С нами с:
    12 окт 2012
    Сообщения:
    3.625
    Симпатии:
    158
    да. но. если сигнатуры у методов идентичные, значит нет никакой неоднозначности, по сути. это ведь интерфейс всего лишь. реализации методов нет.
    реализуя этот метод у класса, совершенно неважно какой метод интерфейса раскрыт - ибо они идентичные полностью. я именно об этом.
    ромбовидное наследование это немного не то, мне кажется. ибо тут речь про интерфейсы а не про множественное наследование классов.
    говорят что в данном случае поведение пыха отличается, как раз, от с++ и явы там(в них такое возможно). завтра на работе проверю.
     
  19. MiksIr

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

    С нами с:
    29 ноя 2006
    Сообщения:
    2.339
    Симпатии:
    44
    Есть объект - это, по сути, набор данных. С данными связана область их видимости. Есть наследование классов, но нет наследования объектов, объект содержит в себе данные всей иерархии классов. А оператор дампа структуры данных все это выводит - удивляет, что кого-то это удивляет. Скрытие данных - это по сути механизм реализации соглашений между программистами, он может быть достигнут и без языковых конструкций protected/private, а, например, соглашением наимнования свойств и методов.

    Добавлено спустя 10 минут 20 секунд:
    В большинстве случаев если у интерфейсов пересекаются названия методов - то проблема в плохом проектировании интерфейсов.
    Но если это все же как-то случилось, но верх невежества говорить, что одинаково названные методы _разных_ интерфейсов, хоть и с одинаковой сигнатурой можно как-то реализовать одним методом. Это просто непонимание сути интерфейса.
     
  20. runcore

    runcore Старожил

    С нами с:
    12 окт 2012
    Сообщения:
    3.625
    Симпатии:
    158
    удивляет не сам факт наследования приватов, а то что в доках об этом четко не сказано. отсюда возникают додумки, неоднозначности и возможно, ожидание другого поведения.
    Во-первых, расскажи это создателям Java, c++, C# ... они вполне позволяют создавать реализацию метода, описанного в разных интерфейсах но с одинаковыми сигнатурами. Вот невежды какие.

    Во-вторых, обратимся к вики:
    т.е. дело не в невежестве, а в том что разработчики сами выбирают реализацию исходя из концепций заложенных в ЯП.

    В-третьих, ты непонял о чем я. я не говорил что поведение в пхп неправильное или плохое, я лишь сказал что оно отличается от других языков, и от моего личного понимания интерфейсов. И ждал обсуждения и идей - почему в пхп ИМЕННО ТАК реализовали это поведение. Если для тебя всё это очевидно - поделись знаниями, нефиг пальцы гнуть
     
  21. MiksIr

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

    С нами с:
    29 ноя 2006
    Сообщения:
    2.339
    Симпатии:
    44
    Интерфейс - это не набор методов. Интерфейс - это контракт описывающий функциональность. Случай, когда у нас объект должен реализовать обязательно два контракта одной и той же функциональности, пришедших из разных вендорных библиотек... ну в общем он исчещающе мал, хватит и одного контракта.
    А если одинаковые сигнатуры, но контракты описывают разоное, то во-перых, это косяк проектировщика интерфейса, а во-вторых, объект вообще не должен реализовывать два разных функционала, хотя бы из SRP.

    Добавлено спустя 3 минуты:
    Там как раз позволяют создать разные реализации такого метода. Это может быть полезно, да, когда пришли два плохо спроектировнных интерфейса. Но все-равно, необходимость этого бывает редко.
    А если язык позволяет тупо определелить реализацию одного метода двех контрактов... ничего хорошего в этом нет, в общем ;)

    Добавлено спустя 2 минуты:
    Потому-что с точки зрения работы программиста с объектом - они не наследуются. А внутреннюю структуру хранения объекта и как интерпретатор с ним работает - доументация не описывает. Частично может помочь изучение возможности классов рефлексии. Доступ к "закрытым" свойствам и методам может потребоваться, например, при написании юнит-тестов.
     
  22. artoodetoo

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

    С нами с:
    11 июн 2010
    Сообщения:
    11.128
    Симпатии:
    1.248
    Адрес:
    там-сям
    Вообще-то принято тестировать надо только публичные методы.
     
  23. Fell-x27

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

    С нами с:
    25 июл 2013
    Сообщения:
    12.156
    Симпатии:
    1.771
    Адрес:
    :сердА
    Поведение пхп отличается от других языков? Отличается от личного понимания, то есть, идет несколько вразрез с ожиданиями, то есть поведение, местами непредсказуемое? Поздравляю, ты только что познал всю суть PHP.
     
  24. igordata

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

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    Всю мощь
     
  25. MiksIr

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

    С нами с:
    29 ноя 2006
    Сообщения:
    2.339
    Симпатии:
    44
    В идеале - да. На практике такое неплохо работает при TDD, в иных случаях, увы, бывает всякое.
    Не говоря уже о том, что есть еще protected, который тоже нужно тестировать, ибо это тоже контракт.