Почему директива друга отсутствует в Java? - PullRequest
16 голосов
/ 10 января 2011

Мне было интересно, почему Java была разработана без директивы friend, которая доступна в C ++, чтобы обеспечить более точный контроль над тем, какие методы и переменные экземпляра доступны вне пакета, в котором был определен класс.

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

Ответы [ 8 ]

10 голосов
/ 10 января 2011

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

Я бы сказал, что чрезвычайно большое количество строк Java в производстве на данный момент может подтвердить, что ключевое слово friend на самом деле не большая потеря :)

Пожалуйста, смотрите ответ @ dwb по некоторым более конкретным причинам.

9 голосов
/ 10 января 2011

Вот несколько причин, которые мне не нравятся:

  • друг не требуется.Это удобно, но не обязательно
  • Друг поддерживает плохой дизайн.Если одному классу требуется доступ друга к другому, вы делаете это неправильно.(см. выше, удобно, не обязательно).
  • друг ломает инкапсуляцию.По сути, все мои рядовые принадлежат мне, и этому парню там (моему другу).
6 голосов
/ 27 мая 2013

Только очень наивный и неопытный программист будет выступать против друзей.Конечно, он может быть использован не по назначению, но так же как и общедоступные данные, но эта возможность предоставляется.

Вопреки распространенному мнению, во многих случаях, в частности, для инфраструктурных возможностей, когда дружественный доступ ведет к ЛУЧШЕМУ дизайну, а не худшему.Инкапсуляция часто нарушается, когда метод ОБЯЗАТЕЛЬНО становится публичным, когда его действительно не должно быть, но у нас нет выбора, потому что Java не поддерживает друзей.

4 голосов
/ 10 января 2011

В дополнение к вышеупомянутой видимости пакета, Java также предлагает внутренние и анонимные классы, которые не только являются друзьями по умолчанию, но также автоматически имеют ссылку на содержащий класс. Поскольку создание таких вспомогательных классов, вероятно, является единственным разумным способом использования friend в C ++, Java не нуждается в этом, поскольку у него есть другой механизм для этого. Итераторы - очень хороший пример этого.

2 голосов
/ 23 июля 2013

Полностью согласен с утверждением spaceghost в его ответе

Вопреки распространенному мнению, во многих случаях, в частности, для возможностей инфраструктуры, когда доступ с друзьями приводит к ЛУЧШЕМУ дизайну, а не худшему.

Мой пример прост - если класс A должен предоставить специальный «дружественный» интерфейс классу B в Java, мы должны поместить их в один и тот же пакет. Без исключений. В этом случае, если A - друг B, а B - друг C, A должен быть другом C, что не всегда верно. Эта «транзитивность дружбы» нарушает инкапсуляцию больше, чем любые проблемы, к которым может привести дружба в C ++.

2 голосов
/ 10 января 2011

По моему мнению, некоторая особенность друга (не обязательно очень похожая на C ++) была бы очень полезна в некоторых ситуациях в Java.В настоящее время у нас есть пакет приватных / стандартных хаков доступа, позволяющих совместную работу между тесно связанными классами в одном и том же пакете (например, String и StringBuffer), но это открывает частный интерфейс реализации для всего пакета.Между пакетами у нас есть злые взломы отражений, которые вызывают целый ряд проблем.

В Java это немного усложняет.C ++ игнорирует ограничения доступа при разрешении перегрузок функций (и аналогичных) - если программа компилирует #define private public, ничего не должно делать.Java (в основном) отбрасывает недоступных членов.Если нужно принять во внимание дружбу, то решение является более сложным и менее очевидным.

2 голосов
/ 10 января 2011

Просто чтобы добавить к другим ответам:

По умолчанию видимость пакета в Java.Таким образом, вы могли бы вызывать все классы в одном и том же пакете соседей.В этом случае у вас есть явный контроль над тем, что вы показываете соседям - просто членам с видимостью пакета.

Итак, это не совсем друг, но может быть похожеИ да, это тоже приводит к плохому дизайну ...

2 голосов
/ 10 января 2011

Почему бы просто не подумать, что Java требует, чтобы классы друзей находились в одном месте?Доступность частного пакета позволяет каждому из одного пакета получить доступ к этим членам.Таким образом, вы не только ограничены явно объявленными друзьями, но и позволяете любому (существующему или будущему) другу изменять некоторых участников, специально предназначенных для этой цели (но не ваши личные вещи).Вы все еще можете полностью положиться на инкапсуляцию.

...