Почему в Java нет модификатора доступа «только для подклассов»?


16

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

public - любой класс может использовать этот метод.

protected - классы в одном пакете и подклассы в любом пакете могут использовать этот метод.

private - только этот класс может использовать этот метод.

no modifier («пакет приватный») - только классы в одном пакете могут использовать этот метод.

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

Поэтому я должен объявить эти полезные методы в суперклассе publicили protected, который предоставляет их всем остальным классам, по крайней мере, в пакете. Даже если они предназначены только для использования подклассами.

Есть ли причина, по которой subclasses-onlyв Java нет модификатора доступа? Это кажется мне очень странным. Я что-то пропустил?

Кроме того, subclasses-onlyмодификатор доступа также будет полезен, когда вы хотите выставлять переменные только подклассам. Что со мной случается много.

Ответы:


10

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

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


15
«и следит за тем, чтобы только родительский класс и его подклассы находились в одном пакете». Теперь, как можно это сделать ?!
JimmyB

1
И тогда вы не можете использовать модификатор доступа только для пакета. И вам нужно глупое количество пакетов. Это не практическое решение.
user253751

13

У Java изначально был такой модификатор. Он был написан, private protectedно удален в Java 1.0.

Я предполагаю, что это был суждение, что дополнительная сложность не стоила затрат.

Каждая языковая функция имеет свою стоимость: обучая ее новым программистам; в документации; в реализации его в компиляторе, JVM и инструментах разработки; в рассуждениях о правильности программы; в сдерживании будущей языковой эволюции; и более. Языковые функции взаимодействуют друг с другом, потенциально с N 2 взаимодействиями.

Какой процент Java-программистов прочитал спецификации языка Java и VM? Бьюсь об заклад, это небольшой процент, который требует еще более простой язык ради понятности и технических продуктов, от которых мы можем зависеть

Преимущество этой private protectedфункции было небольшим, поскольку пакет является основным модульным модулем.


1
так была версия Java до 1.0?
Марк Йисри

1
@MarkYisri Java имела публичные альфа- и бета-версии в 1995 году, и против них было написано немало кода.
Дэвид

4

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

ВЫ: Скажем, вы хотите сделать x, вы вызываете метод doX .. DEV: Скажите мне больше ... каковы аргументы?

Это публично ...

ВЫ: В doX я звоню ... DEV: Ого, слишком много информации, мне все равно. Я просто хочу знать, как его использовать. Скажи мне что-нибудь еще.

Это личное ...

ВЫ: При создании подклассов у меня есть doX и doY, которые вызывают doIt, что делает ... DEV: Да, я собираюсь создать подкласс, расскажите мне больше ...

Это защищено ...

ВЫ: Я ухожу в отпуск через час, я уйду на следующие 6 месяцев. Босс говорит, что этот щенок твой! До свидания. DEV: Подожди, не уходи, расскажи мне все ...

Это пакет.

ВЫ: Метод doItWhen вызывается только этим классом, и он не изменился за десять лет. Это ... DEV: Вау, мы до 50 минут. Следующее свойство, и говорить быстрее.

Это защищенный частный ...


3

Это уже существует. Это защищено.

Вы можете контролировать, какие классы существуют в пакете. Если в пакете нет другого класса и данная переменная или метод защищены, это «только подклассы».

Тем не менее, еще раз, вы можете контролировать, какие классы существуют в пакете. Вы можете просто не использовать защищенные методы или переменные.


3
Могу ли я добавить класс в какой-либо пакет, кроме одного из ваших зарезервированных системных пакетов, даже в ваш, в который вы не собираетесь добавлять классы?
Дэвид Моулз

@David IIRC Да, но он не позволит вам получить доступ к полям пакета из другого JAR-файла, поэтому даже если вы поместите его в тот же пакет, если он находится в другом JAR-файле, вы не сможете получить к нему доступ. Однако, если вы ссылаетесь на тот же JAR-файл, то да, вы можете получить к нему доступ, но если вы можете изменить рассматриваемый JAR-файл, вы также можете легко изменить модификатор доступа.
Pokechu22

1
@ Pokechu22 Я думаю, что вы должны утвердительно запечатать JAR, чтобы получить эту защиту, но хороший момент.
Дэвид
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.