В Java, почему члены класса доступны по умолчанию для членов одного и того же пакета?
Я понимаю, что в отличие от C++, если я не указываю "public" или "private" при объявлении члена данных, к нему можно получить доступ из любого места в одном и том же пакете.
Разработчики языка Java могли бы выбрать противоположное, но вместо этого они предпочли сделать общедоступными члены класса (в том же пакете) по умолчанию.
Есть идеи почему?
7 ответов
Они не являются публичными, они доступны для членов одного пакета. Идея Java заключается в том, что данный пакет представляет собой согласованный набор взаимодействующих обязанностей, поэтому по умолчанию они должны иметь возможность взаимодействовать.
Вы всегда можете использовать определенный уровень доступа, если хотите использовать другую семантику.
Видимость по умолчанию в Java является закрытой для пакета. Это означает, что вы можете получить доступ к этим объектам, если из одного пакета. Я не знаю, почему вы думаете, что видимость по умолчанию является публичной.
Я не знаю решения от Sun, потому что они изобрели Java, но ИМХО, это потому, что вам нужны частные типы пакетов гораздо чаще, чем частные или публичные классы.
Например, если вы создадите API в org.example.myapi.*, Вы попытаетесь сделать так, чтобы вызовы вашего API извне требовали как можно меньшего количества классов, чтобы сохранить простоту мышления, и всех вспомогательных классов, которые вы должны позволить API делать то, что они должны, не должно быть видно снаружи. В большинстве случаев вам нужно больше вспомогательных классов API для закрытых пакетов, чем для открытых классов вызовов API.
@anOOb написал это в комментарии... и это заслуживает тщательного ответа.
Я был приятно удивлен, когда Java позволил мне установить элемент данных одного класса из разностного класса (в отдельном файле), так как мне не пришлось проходить через сложность создания средства доступа. Это удобнее, но не против одного из принципов ОО?
Это на самом деле глубже, чем ОО. Этот принцип является принципом инкапсуляции данных, и он также применим к не-OO-дизайну.
Основной целью аксессоров и мутаторов является инкапсуляция государства; т.е. чтобы детали реализации класса не были видны за пределами класса. Есть две основные причины для этого:
- Это упрощает рассуждения о поведении класса, если вы контролируете или запрещаете доступ к его внутреннему состоянию.
Это облегчает изменение типа реализации и инвариантов переменной состояния. Если в коде, использующем класс, для доступа к состоянию объекта используются только аксессоры / мутаторы (т. Е. Геттеры / сеттеры), то вы часто можете вносить изменения в представление состояния классов и инварианты, скрывая эффекты изменений от вызывающих; например, вот тривиальный пример
private int counter; public int getCounter() { return counter; }
становится
private long counter; public int getCounter() { return (int)counter; } public long getLongCounter() { return counter; }
Есть еще две причины, по которым мы используем аксессоры / мутаторы в Java:
Поведение метода доступа или метода-мутатора обычно может быть переопределено в подклассе. Напротив, в Java вы не можете переопределить или даже изменить видимость выставленного атрибута.
Существует множество фреймворков / инструментов, которые зависят от ваших классов, имеющих методы доступа и мутаторы с именами / сигнатурами методов, которые соответствуют соглашениям спецификации JavaBeans.
Также следует отметить, что простые методы получения и установки встроены JIT-компилятором и, следовательно, оказывают минимальное влияние на производительность.
Вы не должны думать о создании аксессоров как о "хлопотах", которых вам следует избегать. Фактически, методы доступа (и мутаторы) являются важной частью написания хорошего кода Java. Это считается "наилучшей практикой", и типичные программы проверки стиля / ошибок будут отмечать открытые переменные состояния как проблемы.
Просто для справки:
Уровни доступа
-------------------------------------------------- Модификатор класса пакета подкласс мира -------------------------------------------------- общедоступный ГГГГ защищенный YYYN без модификатора YYNN частный YNNN
Я бы просто сказал, что было бы лучше, если бы они сделали уровень доступа по умолчанию private
, Идея была, вероятно, как отмечают другие, что package
уровень доступа будет наиболее часто используемым уровнем доступа, поскольку пакеты "представляют собой согласованный набор взаимодействующих обязанностей" ( Visage). Однако оказалось, что private
является наиболее часто используемым уровнем доступа.
ИМО, дизайнеры Java будут менять спецификации, чтобы сделать private
уровень доступа по умолчанию, если у них была машина времени.
Ваше предположение неверно; поля не являются общедоступными по умолчанию. В таблице ниже описаны все уровни видимости в Java:
Modifier Class Package Subclass World
public Y Y Y Y
protected Y Y Y N
no modifier Y Y N N
private Y N N N
Более подробная информация здесь: http://download.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html