За последние 24 часа нас посетил 59091 программист и 1811 роботов. Сейчас ищет 951 программист ...

ООП. Наследование. Какая - то магия.

Тема в разделе "PHP для новичков", создана пользователем Rezovskij, 2 окт 2016.

  1. Rezovskij

    Rezovskij Новичок

    С нами с:
    18 фев 2016
    Сообщения:
    84
    Симпатии:
    1
    Данный код при вызове команды echo отобразить приватное свойство класса А (то есть результат выполнения равняется значению 1),оно ведь приватное , как так? Чего - то я не понимаю.

    Код (Text):
    1. class A
    2. {
    3.    
    4.     private $k = 1;
    5.  
    6.     public function check()
    7.     {
    8.         return $this->k;
    9.     }
    10. }
    11.  
    12. class B extends A
    13.  
    14. {
    15.     public $k = 5;
    16.  
    17. }
    18.  
    19. $o = new B();
    20. echo $o->check();
     
  2. Deonis

    Deonis Старожил

    С нами с:
    15 фев 2013
    Сообщения:
    1.521
    Симпатии:
    504
    Лично я не могу понять, что вас смущает. Вы не обращаетесь к приватному свойству, а вызываете публичный метод, который возвращает значение этого свойства. Дочерние классы не наследуют приватные методы и свойства, поэтому в классе B, вы его переопределить не можете. Собственно, абсолютно логично, что на выходе, вы получаете значение 1.
     
  3. [vs]

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

    С нами с:
    27 сен 2007
    Сообщения:
    10.559
    Симпатии:
    632
    @Rezovskij приват это прям ващще ващще личное, используй protected чтобы закрыть свойство извне, но открыть наследникам.
     
  4. Rezovskij

    Rezovskij Новичок

    С нами с:
    18 фев 2016
    Сообщения:
    84
    Симпатии:
    1
    меня смущает тот факт, что к свойству обращается объект класса B хоть и в публичном методе. И Нелогично, что к приватному свойству родительского класса может обратиться объект дочернего. Мб я что-то путаю?
     
  5. [vs]

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

    С нами с:
    27 сен 2007
    Сообщения:
    10.559
    Симпатии:
    632
    @Rezovskij конечно путаешь, к приватному свойству родительского класса НЕ обращается объект дочернего, потому что check() не перезагружена в дочернем классе. Используется check() родительского класса и для неё приватное свойство доступно.
    --- Добавлено ---
    PHP:
    1. class A
    2. {
    3.  
    4.     private $k = 1;
    5.     public function check()
    6.     {
    7.         return $this->k;
    8.     }
    9. }
    10. class B extends A
    11. {
    12.     public $k = 5;
    13.     public function check()
    14.     {
    15.         return $this->k;
    16.     }
    17. }
    18. $o = new B();
    19. echo $o->check();
     
  6. mkramer

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

    С нами с:
    20 июн 2012
    Сообщения:
    8.600
    Симпатии:
    1.764
    Да нет, обращается-то как раз объект дочернего класса, но к методу, определённому в родительском классе. То, по поводу чего я как-то с @askanim разругался - распространённое убеждение, что приватные свойства не наследуются. Наследуются, у объектов дочернего класса они есть, но при этом недоступны из методов, определённых в дочернем классе. Но физически, в памяти, отведённой под экземпляр, они всё равно висят, что и показывает данный пример. Весь смысл наследования в любом языке - что объект дочернего класса автоматически является объектом родительского.

    А вот то, что php позволяет в дочернем классе объявить свойство с тем же именем, и потом ведёт себя так, что у класса есть два свойства с одним именем, это, ИМХО, недоработка авторов php
     
  7. [vs]

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

    С нами с:
    27 сен 2007
    Сообщения:
    10.559
    Симпатии:
    632
    Не вижу никакого противоречия. Приватные свойства нужны для обеспечения работы методов, объявленных именно в родительском классе. Это могут быть даже приватные методы. И будет нехорошо, если в дочернем по стечению обстоятельств окажется одноименное свойство с другим значением. Чтобы php не вёл себя так, будто у него два свойства с одним именем, специально придуман protected, а если private будет вести себя так же, то какой в нём смысл?
     
  8. mkramer

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

    С нами с:
    20 июн 2012
    Сообщения:
    8.600
    Симпатии:
    1.764
    Я бы давал ошибку, если бы я был автором интерпретатора. Не претендую на абсолютную правильность, но это моё мнение
     
  9. Rezovskij

    Rezovskij Новичок

    С нами с:
    18 фев 2016
    Сообщения:
    84
    Симпатии:
    1
    Друзья, попробуем резюмировать? Так и не получается понять механизм наследования в данном случае. Вопрос все тот же: Почему объект дочернего класса обратившись к родительскому методу chek(), в ктором выражение $this->k означает, тоже самое что и $о->k. Соответсвенно обьект дочеренего класса обращается через метод к приватному свойству родит ельского, что не должно соответствовать поведению приватного свойствп
     
  10. Rezovskij

    Rezovskij Новичок

    С нами с:
    18 фев 2016
    Сообщения:
    84
    Симпатии:
    1
    Есть ли ЯП с подобной моделью наследования? Мб в другом данный механизм в документации хорошо опичан.
     
  11. mkramer

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

    С нами с:
    20 июн 2012
    Сообщения:
    8.600
    Симпатии:
    1.764
    Если речь идёт не про static-свойства, то фактически это свойства объектов, а не классов. Абсолютно все свойства, объявленные в родительском классе, переходят в наследуемый класс, но доступны из методов, объявленных в родительском классе только protected и public. Методам, которые не объявлены в классе-наследнике, а объявлены в родительском классе, приватные свойства родительского всё равно доступны. Так происходит во всех ЯПах, в C++, в Java, в Delphi - тоже. Если в дочерних классах объявлены не-приватные свойства с таким же именем, то методы, определённые в родительском классе будут всё равно обращаться приватным свойствам родительского класса (и этот момент оказывается в C++ также реализован, я специально проверил сейчас http://ideone.com/B1JEc8). protected и public свойства в php будут перекрыты наследником.

    Так что всё соответствует поведению приватных свойств. Если бы было так, как вы хотите, неперекрытые методы родительского класса отваливались бы от наследников, что не есть гуд :)
     
    Rezovskij нравится это.
  12. mkramer

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

    С нами с:
    20 июн 2012
    Сообщения:
    8.600
    Симпатии:
    1.764
    опечатка. объявленных в наследнике
     
  13. Fell-x27

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

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

    Гляди, @Rezovskij, простое объяснение. Есть класс Жигули. Есть класс Мерседес. Они отличаются, но они оба - автомобили. Все, что у них общее мы выносим в класс Машина. В классе Машина есть свойство Бензин. И есть метод Отдать_порцию_бензина. При этом свойство Бензин, для удобства, спрятано в private.

    А теперь скажи,что нелогичного в том, что двигатель, который и у Жигулей и у Мерседеса свой собственный, а не унаследованный, обращается не напрямую к свойству Бензин, а к методу Отдать_порцию_бензина у топливной системы?

    Он понятия не имеет, сколько осталось бензина, какой он, какая у него температура там, или еще что. Двигатель просто хочет его. Он не должен проверять его, следить за ним. Он - двигатель. А вот публичный метод, к которому он обращается, может это все проверить, сделать выводы, вернуть результат или отказать.

    Один из постулатов ООП - инкапсуляция, добро пожаловать :)
     
    Rezovskij нравится это.