Вопрос

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

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

Это было полезно?

Решение

Вот несколько причин, которые приходят мне в голову:

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

Другие советы

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

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

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

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

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

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

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

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

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

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

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

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

Полностью согласен с заявлением spaceghost в его ответ

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top