А в чем проблема ? Есть кейсы когда это ломает архитектуру приложения ? Может поговорим за порядок аргументов в стандартных функциях ?
Конечно читаю, думаю. Но пока не убеждает. Пока всё сводятся к одному, в разных вариантах, - "так сделано" (в ПХП и в Java может быть - не знаю, не проверял). Но аргумент, почему это правильно, очень сомнительный.
@Chushkin, а как ты реализуешь иначе к примеру метод, сравнивающий два объекта? Все приватные свойства засветишь геттерами? Каждый геттер, между прочим, нарушает инкапсуляцию гораздо в большей степени, чем то, что методам класса доступны приватные свойства объектов этого же класса. Для программиста C++ такого вопроса вообще не может возникнуть, с его перегрузкой операторов, которые иначе не реализовать (в C++ правда ещё есть классы-друзья и функции-друзья, т.е. механизм, с помощью которого класс А может позволить другому классу или функции полный доступ к полям объекта А, но вот это точно чудовищное нарушение инкапсуляции)
Дык ты не хочешь принимать их даже в теории, и отказываешься понимать. Как они тебя, в таком случае, должны убеждать? По лицу бить и заставлять принять их? --- Добавлено --- Это цветочки. В JS объекты разных классов могут давать друг другу методы "погонять" на время. Вот где безумие.
@Chushkin Простенький код на C++, который показывает, как это регулярно используется там Спойлер: Код с++ Код (Text): // Example program #include <iostream> class A { private: int val; public: A(int _v): val(_v) { } bool operator < (const A &other) { return val < other.val; } }; int main() { A a(12), b(14); std::cout << (a < b); } --- Добавлено --- Хотя твой первый пример, всё-таки в C++ не пройдёт. Сейчас попробовал. Ты можешь обращаться к унаследованным protected-свойствам других экземпляров, но только наследника, не родителя.
Во, хороший пример придумал. В принципе, объекты одного класса можно рассматривать как братьев-близнецов. Вот у меня есть брат (правда, не близнец), и это же нормально, что я о нём знаю куда больше, чем все остальные (дату рождения, в каком году он болел коклюшем и т.п.)? Здесь то же самое, фактически. Экземпляры одного класса всё знают друг о друге. Другое дело, что брат может иметь от меня секреты, а экземпляры одного класса друг от друга не могут. Я сейчас не помню, но о каком-то языке я читал, что есть такая штуковина, что всё-таки могут, т.е. там ещё один модификатор доступа есть.
Не, не так. Правильно: ты можешь знать, что у него есть писька, но к его письке ты доступ не имеешь. Потому что он другой объект, хотя вы оба созданы по описанию/декларации "Человек" в котором объявлено/описано это свойство. п.с. Над остальным сказанным я всё-ещё думаю...
Во, нашёл: https://habrahabr.ru/post/267305/ Ты хочешь поведения private[this]. В PHP оно не реализовано, переходи на Scala
Именно. Это правильное поведение согласно логике видимости. Но там тоже неправильно сделали, ибо такое поведение должно быть для private (т.е. по умолчанию), а вот если тебе надо дать доступ к этому свойству извне, тогда _явно_ добавть крыжик (параметр) и будет тебе счастье. Вот это было бы совсем правильно.
@Chushkin чет тупанул и пропустил, что ты - ТС )) А как в твоем представлении, должны работать статичные приватные свойства?
@Chushkin ну что в этом смысле означает "аналогично"? Как должен работать этот код: http://sandbox.onlinephpfunctions.com/code/064c52d05f976ae85ec67700635ba4f9ec0e6e87 ?
Хм, в данном случае так и должно, я так думаю. Я бы это рассматривал так (см.комментарии): PHP: <?php class A { private static $var; public static function set($val) { self::$var = $val; } public function __construct() { echo self::$var; } } A::set('Hello'); // установка значения приватного свойства глобального объекта A $o1 = new A; // создание объекта $o1 наследника глобального объекта A $o1::set('World!'); // установка значения глобального объекта A $o2 = new A; // создание объекта $o2 наследника глобального объекта A Т.е. по сути, "echo self::$var;" выводит значение параметра глобального объекта A, т.к. все статические свойства принадлежат ему. А set() изменяет это свойство. --- Добавлено --- А вообще, static это неоднозначная хрень. С ООП плохо связывается. По сути, я их воспринимаю как глобальные переменные и функции с префиксом имени сайта.
@Chushkin боюсь, ты путаешь понятие объекта и класса. Статичные свойства принадлежат классу. Вместо self:: можно написать A:: и получить тот же результат. Аналогично можно передать объект класса A в метод другого объекта класса A, и вызвать $arg::$var, поскольку это свойство их класса. Со свойствами класса можно работать вообще не создавая объектов. Итого, чтобы ограничить видимость рамками объекта, нужно вводить различный смысл модификаторов доступа для статичных и не-статичных свойств. --- Добавлено --- да, но без статик невозможно реализовать такие паттерны, как синглтон.
1) Ты говоришь о том же, что и выше - "так сделано". Я же говорю о том, как правильно (должно быть). 2) Ещё раз, - класс это тип. При наличии static неявно создаётся нечто глобальное на этапе компиляции. По сути, того же эффекта можно добиться, создав обычный глобальный объект и работая с ним. static просто удобнее в использовании, чем глобальный объект, плюс чуть больше защищённости. п.с. Хотя, на счёт создания глобального на этапе компиляции не уверен - я не знаю как там сделано внутри, не копался. Но это и не важно, важно "вход - выход" и поведение, логика. А по логике, статик - глобальное. Серьёзно?
да, потому что ты назвал это объектом. И в этом нечто хранятся методы, которые потом появляются в объектах, их свойства с дефолтными значениями, даже если бы статики не было, оно бы сущестовало, потому что оно - это и есть класс. ну, а как?
Угу. Если принять за аксиому, что класс это тип, то A:: это обращение к объекту типа A. А когда, как и где этот объект создаётся, пофиг. п.с. Ты же не говоришь, что тип array содержит запись, говоришь, что переменная типа array содержит запись. А когда и как она создаётся, - при компиляции, глобально, статически, локально, динамически - пофиг. Почему у классов/объектов должно быть по другому.
@Chushkin свойство класса это неотъемлемая часть парадигмы ооп. Класс "помещики" априори имеет свойство "количество душ во владении", даже если ни одного помещика в данный момент не существует. --- Добавлено --- Давай по теме, статика это не совсем ооп, но как быть с паттернами?
Вы мне кажется совсем о другом. Вернемся к первому посту Такой подход в java вызовет Exception. Например: Имеем два пакета 1. javaapplication3 2. javaapplication3.newPac И два класса: родитель Код (Text): package javaapplication3; /** * * @author hp */ public class A { protected String test = "bug"; /** * @param args the command line arguments */ public static void main(String[] args) { // TODO code application logic here } public A() { } } наследник Код (Text): package javaapplication3.newPac; import javaapplication3.A; /** * * @author hp */ public class B extends A{ /** * @param args the command line arguments */ public static void main(String[] args) { // TODO code application logic here B b = new B(); } public B() { A a = new A(); System.out.print(a.test); } } на выходе: Код (Text): Exception in thread "main" java.lang.RuntimeException: Uncompilable source code - test has protected access in javaapplication3.A Что и правильно. А в php подобное работает. --- Добавлено --- Т.е. я имею в виду не поняли @Chushkin`a
Ну @Chushkin дальше пишет больше Только с этим можно согласиться, что иметь доступ к защищённым свойствам экземпляров родителя не совсем гуд. Но иметь доступ к приватным свойствам других экземпляров своего класса, по мнению разработчиков большинства языков - нормально, а по мнению ТС - караул.
@mkramer, дальше больше получилось. Я не вникал. Но именно код в первом посте если воспроизвести в java будет exception/ Конечно, все будет работать если оба класса будут находится в одном пакете, тут вступает другое правило "доступ в пределах пакета". Т.е. члены с этим спецификатором доступны для других классов (не важно, наледник он или нет) из того же пакета. --- Добавлено --- Учитывая, что в PHP "пакенты" совсем не те что в Java можно сделать вывод, что они(создатели PHP) решили дать доступ к протектед членам того же типа что и сам класс где создается объект. --- Добавлено --- т.е. PHP: class A { protected $protected = 'Bug!'; } class B extends A{ public function __construct() { $obj = new A; $obj->protected; } } class C extends B{ public function __construct() { $obj = new B; echo $obj->protected; } } $b = new C(); все они типа A/ --- Добавлено --- Я это себе так объяснил.
Во, то что дохтур прописал! Значит из того списка, что был выше (Object Pascal, C++, Java) Java вычёркиваем - у него правильно сделано. Слегка полегчало, - не всё так плохо в мире ЯП. А то тут вчера решили потестить Кларион, на котором я отпахал 15 лет, - оказывается у него так же, как в ПХП. И это сильно меня огорчило, - я то всегда считал кларион хорошим языком. Но факт того, что за 15 лет я ни разу не наткнулся на эту особенность, слегка взбодрило, ибо книга гинеса по мне плачет.