Подтвердить что ты не робот

Окончательный абстрактный класс Java

У меня довольно простой вопрос:

Я хочу иметь Java-класс, который предоставляет один публичный статический метод, который что-то делает. Это просто для целей инкапсуляции (чтобы все было важно в одном классе)...

Этот класс не должен быть ни инстанцирован, ни расширен. Это заставило меня написать:

final abstract class MyClass {
   static void myMethod() {
      ...
   }
   ... // More private methods and fields...
}

(хотя я знал, это запрещено).

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

Но это кажется мне более похожим на "Обходной путь" и СЛЕДУЕТ более вероятно сделать окончательный абстрактный класс...

И я ненавижу обходные пути. Так что для моего собственного интереса: есть ли другой, лучший способ?

4b9b3361

Ответ 1

Ссылка: Эффективное Java 2nd Edition Пункт 4 "Принудительная неинстантируемость с помощью частного конструктора"

public final class MyClass { //final not required but clearly states intention
    //private default constructor ==> can't be instantiated
    //side effect: class is final because it can't be subclassed:
    //super() can't be called from subclasses
    private MyClass() {
        throw new AssertionError()
    }

    //...
    public static void doSomething() {}
}

Ответ 2

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

public enum MyLib {;

   public static void myHelperMethod() { }
}

Этот класс является окончательным, с явно не экземплярами и частным конструктором.

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

Ответ 3

Нет, вам нужно создать частный пустой конструктор, который выдает исключение в теле. Java - это объектно-ориентированный язык, и класс, который никогда не будет создан, сам по себе является обходным!:)

final class MyLib{
    private MyLib(){
        throw new IllegalStateException( "Do not instantiate this class." );
    }

    // static methods go here

}

Ответ 4

Нет, абстрактные классы должны быть расширены. Используйте частный конструктор, это не обходной путь - это способ сделать это!

Ответ 5

Объявить конструктор класса private. Это гарантирует неинвестируемость и предотвращает подкласс.

Ответ 6

Предложения assylias (все версии Java) и Peter Lawrey ( >= Java5) являются стандартным способом в этом случае.

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

Я предлагаю следующее:

public abstract MyClass {

    protected MyClass() {
    }

    abstract void noInstancesPlease();

    void myMethod() {
         ...
    }
    ... // More private methods and fields...

}

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

Мне всегда кажется, что классы полезности JDK (например, java.util.Arrays) были окончательно завершены. Если вы хотите, чтобы у вас был класс Arrays с методами для сравнения, вы не можете, вам нужно сделать отдельный класс. Это будет распространять функции, которые (IMO) принадлежат вместе и должны быть доступны через один класс. Это оставляет вас либо с дико распространенными методами утилиты, либо вам придется дублировать каждый из методов в свой собственный класс.

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

Ответ 7

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

Ответ 8

Это очень простое объяснение в простом английском языке. Абсолютный класс не может быть создан и может быть расширен. Конечный класс не может быть расширен. Теперь, если вы создадите абстрактный класс как последний класс, как вы думаете, собираешься когда-либо использовать этот класс, и что на самом деле является основанием для того, чтобы поставить себя в такую ​​ловушку в первую очередь?

Ответ 9

Проверить этот справочный сайт..

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

Спасибо..