публичные методы в закрытых классах - PullRequest
38 голосов
/ 10 марта 2011

Имеет ли смысл помечать методы как public в закрытых для пакета классах?

class SomePackagePrivateClass
{
    void foo();          // package private method

    public void bar();   // public method
}

Есть ли практическая разница в видимости между foo и bar здесь?

Ответы [ 7 ]

41 голосов
/ 10 марта 2011

Пример использования наследования:

A.java

package pkg1

class A {
  void foo();
  public void bar() {};
}

B.java

package pkg1

public class B extends A{

}

C.java

package pkg2

public class C {
  public void doSomething() {
   B b = new B();
   b.bar(); //ok
   b.foo(); //won't work, since foo() is not visible outside of package 'pkg1'

   A a = new A(); //won't work since A is not visible outside of package 'pkg1'
   a.bar(); //won't work, since a cannot be created
  }
}
19 голосов
/ 10 марта 2011

Если класс не будет расширен другим, более видимым подклассом *, единственная разница - ясность намерения . Объявление всех закрытых пакетов методов затрудняет будущим читателям определение того, какие методы должны вызываться другими классами в том же пакете.

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

9 голосов
/ 10 марта 2011

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

6 голосов
/ 14 мая 2013

Ну ... у меня тоже было это сомнение (вот почему я искал эту тему). Это может быть хороший вопрос.

Но ...

После второй мысли все становится действительно проще, чем мы думали.

Закрытый для пакета метод, это закрытый для пакета метод.

Кажется глупостью? Но ...

Закрытый для пакета метод, даже если его класс унаследован, но он по-прежнему Закрытый для пакета метод.

Теперь это имеет больше смысла? Для более подробного объяснения:

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

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

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

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


Выше приведено объяснение метода приватности пакетов. И случай public-метода точно такой же.

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

В примере OP, поскольку foo() и bar() оба находятся в классе с закрытым пакетом, их видимость в данный момент ограничена частным с пакетом, пока не будут добавлены дополнительные коды (например, наследование).

Надеюсь, это достаточно ясно (и просто).

P.S. таблица контроля доступа Java

5 голосов
/ 10 марта 2011

Это не имеет большого значения, если класс не расширен публичным (или защищенным вложенным) классом.

В качестве последовательности я бы выбрал public. Методы должны быть редкими, кроме public или private.

.

Существует ряд примеров открытых методов в пакете private java.lang.AbstractStringBuilder class. Например, length() общедоступен в AbstractStringBuilder и доступен в общедоступном классе StringBuilder (переопределен в StringBuffer для добавления синхронизации).

3 голосов
/ 22 декабря 2016

Да. Методы public в классе пакета могут быть полезны (хотя они редки). Наглядный пример из библиотеки Java (взятый из классической книги «Эффективная Java»):

Вы когда-нибудь видели java.util.JumboEnumSet, java.util.RegularEnumSet ?? Вероятно, нет, потому что они являются частными и не упоминаются в документации.

Вы когда-нибудь использовали их ?? Вероятно, да. Они возвращаются статическим методом java.util.EnumSet.noneOf(...). Хотя вы не можете создать их самостоятельно, вы можете использовать их публичные методы, когда они возвращаются из этого метода.

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

0 голосов
/ 10 марта 2011

foo имеет default package visibility, где bar имеет public видимость

...