JAVA

индекс
157,29

Abstract и Final class одновременно в языке программирования Java?!

Статья представляет авторское понимание главы из книги Effective Java, Second Edition by Joshua Bloch

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

Для более точного определения обратитесь к официальному туториалу:

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

Сделать класс abstract и final одновременно нам, например, необходимо когда мы ходим создать класс утилит, состоящих из статических методов (например java.lang.Math или java.util.Arrays).


Решение



public class UtilityClass {
  
  private UtilityClass() {
    throw new AssertionError();
  }
  
  ... // реализация статических методов
}


* This source code was highlighted with Source Code Highlighter.


Как известно, конструктор по умолчанию создается только если класс не содержит никаких явных конструкторов. Поэтому, определив у класса приватный конструктор без параметров мы обеспечим запрет на его инстанциирование из кода вне класса. AssertionError не является строго обязательным, но он обеспечивает страхование на случай, если конструктор случайно вызван из класса. Это гарантирует, что класс не будет инстанциирован при любых обстоятельствах (abstract). Эта идиома также предотвращает создание подклассов от данного класса(final). Все конструкторы должны вызывать конструктор суперкласса явно или неявно, а подклассы данного класса не будут иметь доступа к конструктору базового класса.

_________
Текст подготовлен в ХабраРедакторе
+6
4 марта 2010, 17:15
1

комментарии (24)

0
leshka #
не понятно с final. Почему это эквивалентно? Что нам мешает наследоваться и не использовать конструктор?:)
0
feodal #
прочитайте последнее предложение ;)
0
leshka #
точно:) прикольно
–4
spiff #
И чем это лучше, чем сделать final abstract class UtilityClass?
0
feodal #
final abstract для класса не возможно сделать ;)
0
Yupiter #
тем, что нельзя классу быть одновременно final abstract,
в прочем делать такие классы — это странное желание на мой вкус,
а вот описанный паттерн (финальный класс+приватный конструктор) — вполне имеет право на существование
0
Colwin #
IMHO: Насколько я помню определение паттерна (по GoF), данный подход вряд ли можно назвать паттерном.
0
Zorkus #
Это не паттерн, это идиома. Паттерн — более высокий уровень абстракции, он не привязан к языку.
0
PATRICK17 #
Разве не так?
public final class UtilityClass
0
feodal #
final избыточно, если есть все конструкторы приватные.
еще в Вашем варианте можно будет создать экземпляр класса через конструктор по умолчанию, который добавит компилятор
0
PATRICK17 #
в каком моем варианте? я в ваш говорю добавить надо слово final, что оптимальнее, нагляднее для пользователя вашего класса.
0
Colwin #
0
gvsmirnov #
Чем авторское понимание отличается от Блоховского?
Ничем. Вы бы ещё скопипастили.
0
feodal #
У меня не дословный перевод, а мое понимание написанного (сравните с оригиналом при желании). Думаю, что людям будет приятно прочитать про подобные вещи на русском языке, поскольку не все владеют английским и не все знают про книгу Блоха.
–1
gvsmirnov #
Вещь всем известная, и вы ничего нового не привнесли.
Обычно на такое говорят «Спасибо, кэп!».
0
feodal #
Если данный материал Вам известен, то далеко не факт, что остальные тоже с ним знакомы.
+1
Zorkus #
Ну вообще говоря, я согласен с тем, Блох это книга по Java из серии — must have and read again and again.
+1
Guinplaine #
Да, сам так делаю.
Правда, если задуматься — непонятно достоин ли этот мелкий момент внимания.
Всё равно у утилити-классе все методы статические и если кто-то захочет создать экземпляр подобного класса — да пожалуйста, какая разница. Но только никто не захочет потому что тупо незачем.
+1
Colwin #
Многие начинающие программисты, которые еще слабо владеют предметом ООП, наследуют от утилитных классов (встречал при доработке кода в подобных проектах).
+2
Guinplaine #
Да есть и пострашнее ошибки у начинающего программиста.
Эта-то совсем безобидная, багов не сделает.
+1
Colwin #
С точки зрения удобочитаемости лучше помимо приватного конструктора объявлять класс final. Современные IDE по этому модификатору помечают класс специальной иконкой, что позволяет наглядно выделять подобные классы в списке. Также это является дополнительным документированием направления мыслей разработчика.
+1
Zorkus #
Кстати, если уж совсем копнуть вглубь, то в Java (по крайней мере в 1.5.* версиях Sun Hotspot) можно наследоваться от final класса в каком-то смысле ;).

www.wasm.ru/article.php?article=unsjav1
Disclaimer: все это не для того, чтобы использовать, а просто пример того, что в принципе удалять зубы через задний проход наследоваться от final-class иногда возможно.
+1
viat0r #
мда. это ж надо умудриться на основе двух строк из замечательной книги Блоха написать целую статью, а потом еще устроить обсуждение. Браво!
0
feodal #
стараемся ;)

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