Java: доступ к подклассу без доступа к пакету - PullRequest
10 голосов
/ 21 ноября 2010

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

Разве это не совсем наоборот?Допустим, у меня есть класс ControlledInstantiation в некотором пакете.Если у меня есть другой класс Кроме того, свойствоControlledInstantiation расширяет ControlledInstantiation, я не могу вызвать конструктор ControlledInstantiation, если я не установил его как защищенный или общедоступный.И если я установил его в защищенный, теперь любой другой класс в пакете может создавать его экземпляры так часто, как ему хочется.Таким образом, что-то, что обязано заменить его суперклассом (и, синтаксически, есть), получает тот же или меньший доступ к суперклассу, чем то, что выполняет отдельную, но связанную функцию.Это все равно, что сказать своему ребенку, что он не может играть с вашим кошельком, потому что вы не позволите своим соседям делать это, а затем позволить своим соседям спать в вашем доме, потому что это делает ваш ребенок.чем мотивировано это решение и как его обойти?

Ответы [ 3 ]

3 голосов
/ 21 ноября 2010

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

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

  2. Если вы действительно хотите избежать доступа к защищенному методу членами пакета, вы можете решить эту проблему хотя бы во время выполнения с помощью Throwable.getStacktrace ():

    if(!getClass().isAssignableFrom(
        Class.forName(new Throwable().getStackTrace()[1].getClassName()))) {
            throw new IllegalAccessException(
                "This method can be accessed by subclass only");
    }
    
3 голосов
/ 21 ноября 2010

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

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

0 голосов
/ 21 ноября 2010

Вы можете запечатать пакет. См. Спецификацию файла JAR.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...