За последние 24 часа нас посетили 32465 программистов и 1754 робота. Сейчас ищут 907 программистов ...

ООП и "protected в PHP"

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

  1. Abyss

    Abyss Старожил

    С нами с:
    12 дек 2015
    Сообщения:
    1.298
    Симпатии:
    218
    Адрес:
    Default city
    А в чем проблема ? Есть кейсы когда это ломает архитектуру приложения ?
    Может поговорим за порядок аргументов в стандартных функциях ?
     
  2. Chushkin

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

    С нами с:
    17 дек 2010
    Сообщения:
    1.062
    Симпатии:
    91
    Адрес:
    Мещёра, Центр, Болото N3
    Конечно читаю, думаю. Но пока не убеждает. :(
    Пока всё сводятся к одному, в разных вариантах, - "так сделано" (в ПХП и в Java может быть - не знаю, не проверял). Но аргумент, почему это правильно, очень сомнительный.
     
  3. mkramer

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

    С нами с:
    20 июн 2012
    Сообщения:
    8.599
    Симпатии:
    1.764
    @Chushkin, а как ты реализуешь иначе к примеру метод, сравнивающий два объекта? Все приватные свойства засветишь геттерами? Каждый геттер, между прочим, нарушает инкапсуляцию гораздо в большей степени, чем то, что методам класса доступны приватные свойства объектов этого же класса. Для программиста C++ такого вопроса вообще не может возникнуть, с его перегрузкой операторов, которые иначе не реализовать (в C++ правда ещё есть классы-друзья и функции-друзья, т.е. механизм, с помощью которого класс А может позволить другому классу или функции полный доступ к полям объекта А, но вот это точно чудовищное нарушение инкапсуляции)
     
  4. Fell-x27

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

    С нами с:
    25 июл 2013
    Сообщения:
    12.156
    Симпатии:
    1.771
    Адрес:
    :сердА
    Дык ты не хочешь принимать их даже в теории, и отказываешься понимать. Как они тебя, в таком случае, должны убеждать? По лицу бить и заставлять принять их?
    --- Добавлено ---
    Это цветочки. В JS объекты разных классов могут давать друг другу методы "погонять" на время. Вот где безумие.
     
  5. mkramer

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

    С нами с:
    20 июн 2012
    Сообщения:
    8.599
    Симпатии:
    1.764
    @Chushkin Простенький код на C++, который показывает, как это регулярно используется там
    Код (Text):
    1. // Example program
    2. #include <iostream>
    3.  
    4. class A {
    5.     private:
    6.        int val;
    7.     public:
    8.        A(int _v): val(_v)
    9.        {
    10.        }
    11.      
    12.        bool operator < (const A &other)
    13.        {
    14.            return val < other.val;
    15.        }
    16. };
    17.  
    18. int main()
    19. {
    20.     A a(12), b(14);
    21.    
    22.     std::cout << (a < b);
    23. }
    --- Добавлено ---
    Хотя твой первый пример, всё-таки в C++ не пройдёт. Сейчас попробовал. Ты можешь обращаться к унаследованным protected-свойствам других экземпляров, но только наследника, не родителя.
     
    artoodetoo нравится это.
  6. mkramer

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

    С нами с:
    20 июн 2012
    Сообщения:
    8.599
    Симпатии:
    1.764
    Во, хороший пример придумал. В принципе, объекты одного класса можно рассматривать как братьев-близнецов. Вот у меня есть брат (правда, не близнец), и это же нормально, что я о нём знаю куда больше, чем все остальные (дату рождения, в каком году он болел коклюшем и т.п.)? Здесь то же самое, фактически. Экземпляры одного класса всё знают друг о друге. Другое дело, что брат может иметь от меня секреты, а экземпляры одного класса друг от друга не могут. Я сейчас не помню, но о каком-то языке я читал, что есть такая штуковина, что всё-таки могут, т.е. там ещё один модификатор доступа есть.
     
  7. Chushkin

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

    С нами с:
    17 дек 2010
    Сообщения:
    1.062
    Симпатии:
    91
    Адрес:
    Мещёра, Центр, Болото N3
    Не, не так. Правильно: ты можешь знать, что у него есть писька, но к его письке ты доступ не имеешь. Потому что он другой объект, хотя вы оба созданы по описанию/декларации "Человек" в котором объявлено/описано это свойство.

    п.с. Над остальным сказанным я всё-ещё думаю...
     
  8. mkramer

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

    С нами с:
    20 июн 2012
    Сообщения:
    8.599
    Симпатии:
    1.764
    Во, нашёл: https://habrahabr.ru/post/267305/ Ты хочешь поведения private[this]. В PHP оно не реализовано, переходи на Scala :)
     
  9. Chushkin

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

    С нами с:
    17 дек 2010
    Сообщения:
    1.062
    Симпатии:
    91
    Адрес:
    Мещёра, Центр, Болото N3
    Именно. Это правильное поведение согласно логике видимости.
    Но там тоже неправильно сделали, ибо такое поведение должно быть для private (т.е. по умолчанию), а вот если тебе надо дать доступ к этому свойству извне, тогда _явно_ добавть крыжик (параметр) и будет тебе счастье. Вот это было бы совсем правильно.
     
  10. [vs]

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

    С нами с:
    27 сен 2007
    Сообщения:
    10.559
    Симпатии:
    632
    @Chushkin чет тупанул и пропустил, что ты - ТС ))
    А как в твоем представлении, должны работать статичные приватные свойства?
     
  11. Chushkin

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

    С нами с:
    17 дек 2010
    Сообщения:
    1.062
    Симпатии:
    91
    Адрес:
    Мещёра, Центр, Болото N3
    Аналогично.
    Разве должна быть разница?
     
  12. Fell-x27

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

    С нами с:
    25 июл 2013
    Сообщения:
    12.156
    Симпатии:
    1.771
    Адрес:
    :сердА
    Остается лишь одно решение - ты должен создать свой ЯП.
     
  13. [vs]

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

    С нами с:
    27 сен 2007
    Сообщения:
    10.559
    Симпатии:
    632
    @Chushkin смысле? Статичные свойства ведь работают без создания экземпляров.
     
  14. Chushkin

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

    С нами с:
    17 дек 2010
    Сообщения:
    1.062
    Симпатии:
    91
    Адрес:
    Мещёра, Центр, Болото N3
    И что? Как это влияет на видимость?
     
  15. [vs]

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

    С нами с:
    27 сен 2007
    Сообщения:
    10.559
    Симпатии:
    632
  16. Chushkin

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

    С нами с:
    17 дек 2010
    Сообщения:
    1.062
    Симпатии:
    91
    Адрес:
    Мещёра, Центр, Болото N3
    Хм, в данном случае так и должно, я так думаю.
    Я бы это рассматривал так (см.комментарии):
    PHP:
    1. <?php
    2. class A {
    3. private static $var;
    4. public static function set($val) {
    5.    self::$var = $val;
    6. }
    7.  
    8. public function __construct() {
    9.   echo self::$var;
    10. }
    11. }
    12.  
    13. A::set('Hello'); // установка значения приватного свойства глобального объекта A
    14. $o1 = new A; // создание объекта $o1 наследника глобального объекта A
    15. $o1::set('World!'); // установка значения глобального объекта A
    16. $o2 = new A; // создание объекта $o2 наследника глобального объекта A
    Т.е. по сути, "echo self::$var;" выводит значение параметра глобального объекта A, т.к. все статические свойства принадлежат ему. А set() изменяет это свойство.
    --- Добавлено ---
    А вообще, static это неоднозначная хрень. С ООП плохо связывается.
    По сути, я их воспринимаю как глобальные переменные и функции с префиксом имени сайта.
     
  17. [vs]

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

    С нами с:
    27 сен 2007
    Сообщения:
    10.559
    Симпатии:
    632
    @Chushkin боюсь, ты путаешь понятие объекта и класса. Статичные свойства принадлежат классу. Вместо self:: можно написать A:: и получить тот же результат. Аналогично можно передать объект класса A в метод другого объекта класса A, и вызвать $arg::$var, поскольку это свойство их класса. Со свойствами класса можно работать вообще не создавая объектов.
    Итого, чтобы ограничить видимость рамками объекта, нужно вводить различный смысл модификаторов доступа для статичных и не-статичных свойств.
    --- Добавлено ---
    да, но без статик невозможно реализовать такие паттерны, как синглтон.
     
  18. Chushkin

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

    С нами с:
    17 дек 2010
    Сообщения:
    1.062
    Симпатии:
    91
    Адрес:
    Мещёра, Центр, Болото N3
    1) Ты говоришь о том же, что и выше - "так сделано". Я же говорю о том, как правильно (должно быть).
    2) Ещё раз, - класс это тип. При наличии static неявно создаётся нечто глобальное на этапе компиляции.
    По сути, того же эффекта можно добиться, создав обычный глобальный объект и работая с ним. static просто удобнее в использовании, чем глобальный объект, плюс чуть больше защищённости.
    п.с. Хотя, на счёт создания глобального на этапе компиляции не уверен - я не знаю как там сделано внутри, не копался. Но это и не важно, важно "вход - выход" и поведение, логика. А по логике, статик - глобальное.

    Серьёзно?
     
  19. [vs]

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

    С нами с:
    27 сен 2007
    Сообщения:
    10.559
    Симпатии:
    632
    да, потому что ты назвал это объектом.
    И в этом нечто хранятся методы, которые потом появляются в объектах, их свойства с дефолтными значениями, даже если бы статики не было, оно бы сущестовало, потому что оно - это и есть класс.
    ну, а как?
     
  20. Chushkin

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

    С нами с:
    17 дек 2010
    Сообщения:
    1.062
    Симпатии:
    91
    Адрес:
    Мещёра, Центр, Болото N3
    Угу. Если принять за аксиому, что класс это тип, то A:: это обращение к объекту типа A. А когда, как и где этот объект создаётся, пофиг.
    п.с. Ты же не говоришь, что тип array содержит запись, говоришь, что переменная типа array содержит запись. А когда и как она создаётся, - при компиляции, глобально, статически, локально, динамически - пофиг. Почему у классов/объектов должно быть по другому.
     
  21. [vs]

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

    С нами с:
    27 сен 2007
    Сообщения:
    10.559
    Симпатии:
    632
    @Chushkin свойство класса это неотъемлемая часть парадигмы ооп. Класс "помещики" априори имеет свойство "количество душ во владении", даже если ни одного помещика в данный момент не существует.
    --- Добавлено ---
    Давай по теме, статика это не совсем ооп, но как быть с паттернами?
     
  22. mahmuzar

    mahmuzar Старожил

    С нами с:
    6 апр 2012
    Сообщения:
    4.631
    Симпатии:
    425
    Адрес:
    РД, г. Махачкала.
    Вы мне кажется совсем о другом. Вернемся к первому посту
    Такой подход в java вызовет Exception.
    Например:
    Имеем два пакета
    1. javaapplication3
    2. javaapplication3.newPac

    И два класса:
    родитель
    Код (Text):
    1. package javaapplication3;
    2.  
    3. /**
    4. *
    5. * @author hp
    6. */
    7. public class A {
    8.  
    9.     protected String test = "bug";
    10.  
    11.     /**
    12.      * @param args the command line arguments
    13.      */
    14.     public static void main(String[] args) {
    15.         // TODO code application logic here
    16.     }
    17.  
    18.     public A() {
    19.     }
    20.  
    21. }
    наследник
    Код (Text):
    1. package javaapplication3.newPac;
    2. import javaapplication3.A;
    3.  
    4. /**
    5. *
    6. * @author hp
    7. */
    8. public class B extends A{
    9.    
    10.     /**
    11.      * @param args the command line arguments
    12.      */
    13.     public static void main(String[] args) {
    14.         // TODO code application logic here
    15.         B b = new B();
    16.      
    17.     }
    18.  
    19.    
    20.     public B() {
    21.         A a = new A();
    22.         System.out.print(a.test);
    23.     }
    24.    
    25. }
    на выходе:
    Код (Text):
    1. Exception in thread "main" java.lang.RuntimeException: Uncompilable source code - test has protected access in javaapplication3.A
    Что и правильно. А в php подобное работает.
    --- Добавлено ---
    Т.е. я имею в виду не поняли @Chushkin`a
     
  23. mkramer

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

    С нами с:
    20 июн 2012
    Сообщения:
    8.599
    Симпатии:
    1.764
    Ну @Chushkin дальше пишет больше :) Только с этим можно согласиться, что иметь доступ к защищённым свойствам экземпляров родителя не совсем гуд. Но иметь доступ к приватным свойствам других экземпляров своего класса, по мнению разработчиков большинства языков - нормально, а по мнению ТС - караул.
     
  24. mahmuzar

    mahmuzar Старожил

    С нами с:
    6 апр 2012
    Сообщения:
    4.631
    Симпатии:
    425
    Адрес:
    РД, г. Махачкала.
    @mkramer, дальше больше получилось. Я не вникал. Но именно код в первом посте если воспроизвести в java будет exception/
    Конечно, все будет работать если оба класса будут находится в одном пакете, тут вступает другое правило "доступ в пределах пакета".
    Т.е. члены с этим спецификатором доступны для других классов (не важно, наледник он или нет) из того же пакета.
    --- Добавлено ---
    Учитывая, что в PHP "пакенты" совсем не те что в Java можно сделать вывод, что они(создатели PHP) решили дать доступ к протектед членам того же типа что и сам класс где создается объект.
    --- Добавлено ---
    т.е.
    PHP:
    1. class A {
    2.     protected $protected = 'Bug!';
    3. }
    4. class B extends A{
    5.     public function __construct() {
    6.         $obj = new A;
    7.         $obj->protected;
    8.     }
    9. }
    10. class C extends B{
    11.     public function __construct() {
    12.         $obj = new B;
    13.         echo $obj->protected;
    14.     }
    15. }
    16.  
    17. $b = new C();
    все они типа A/
    --- Добавлено ---
    Я это себе так объяснил.
     
  25. Chushkin

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

    С нами с:
    17 дек 2010
    Сообщения:
    1.062
    Симпатии:
    91
    Адрес:
    Мещёра, Центр, Болото N3
    Во, то что дохтур прописал!
    Значит из того списка, что был выше (Object Pascal, C++, Java) Java вычёркиваем - у него правильно сделано.
    Слегка полегчало, - не всё так плохо в мире ЯП. А то тут вчера решили потестить Кларион, на котором я отпахал 15 лет, - оказывается у него так же, как в ПХП. И это сильно меня огорчило, - я то всегда считал кларион хорошим языком. :(
    Но факт того, что за 15 лет я ни разу не наткнулся на эту особенность, слегка взбодрило, ибо книга гинеса по мне плачет. :)