Почему в частных классах существуют общедоступные методы?

Я просматривал часть кода, которая была чем-то вроде этого

// compare points according to their polar radius
public static final Comparator<Point2D> R_ORDER = new ROrder();
.
.
.
private static class ROrder implements Comparator<Point2D> {
    public int compare(Point2D p, Point2D q) {
        double delta = (p.x*p.x + p.y*p.y) - (q.x*q.x + q.y*q.y);
        if (delta < 0) return -1;
        if (delta > 0) return +1;
        return 0;
    }
}

Почему у нас есть такие общедоступные методы внутри частных статических классов. Какой вред он сделает, если я сделаю ROrder

  • Нестатический
  • Публичный

Ответ 1

ROrder Нестатический

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

ROrder Публичный

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

Почему у нас есть такие общедоступные методы внутри частных статических классов.

В этом случае, поскольку вы реализуете interface Comparator, и вы передадите этот компаратор для других целей, таких как сортировка, и вы бы хотели, чтобы класс Collections имел видимость метода compare, поэтому метод должен быть public, даже если класс, реализующий интерфейс, private.

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

Логическое использование

Этот класс хочет, чтобы строка была в некотором формате.

public class SomeClass{

     private static class StringHelper{
          //will do the task of parsing and validating that string object
     } 
}

Теперь в этом случае вы не захотите сохранить StringHelper class public, так как его использование слишком локализовано для повторного использования. Поэтому вы предпочтете подчеркнуть это, сохранив его private. И могут быть методы public, если StringHelper реализован какой-то интерфейс.

UPDATE:

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

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

Ответ 2

Этот класс реализует Comparator и поэтому должен реализовать свои методы. Методы реализации не могут быть static. Кроме того, поскольку методы интерфейса неявно public, они должны быть объявлены public, независимо от видимости класса. Попытайтесь не делать этого, и он не сможет скомпилировать. Это, конечно, причина, по которой здесь объявлено public - этого не может быть.

Это верно, независимо от того, содержит ли класс класса static или public. Здесь может быть любой из этих вещей, и внутри метода все равно должен быть public и не static.

Другие методы, которые не реализуют интерфейс, могут быть private и, по логике, вероятно, должны быть внутри класса private, так как не было бы смысла объявлять его иначе - но это было бы разрешено синтаксисом Java.

Ответ 3

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

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

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

Ответ 4

Этот класс является приватным, потому что разработчик не хотел, чтобы ROrder был создан в другом месте. Но экземпляр можно получить через константу R_ORDER из других классов.

Метод общедоступен по двум причинам: во-первых, compare определяется в интерфейсе Comparator. Во-вторых, поскольку R_ORDER доступен из других классов, более чем удобно вызывать метод на этом объекте. В этом случае это compare.

Наконец, если класс не был статическим, он сохранил ссылку на родительский класс, который почти всегда не нужен