Этот интересный и важный вопрос задали одному из моих читателей во время телефонного собеседования на должность Java-разработчика. Хотя он и знал, что сделать абстрактный класс
Многие Java-разработчики путаются при ответе на этот вопрос из-за формулировки. Даже если человек, которому задали вопрос, знаком с общей концепцией, он может не сообразить, что класс, после объявления в нём абстрактного метода становится абстрактным, а сделать абстрактный класс
То же самое произойдет, если вы введете этот код в блокноте и скомпилируете его при помощи утилиты javac из командной строки. Согласно спецификациям Java, как только вы объявляете внутри класса абстрактный метод, этот класс становится абстрактным классом, а раз сделать абстрактный класс
final-ьным в языке Java нельзя, его смутила формулировка вопроса. Ответ прост: нет, в final-классе не может быть абстрактных методов. Почему? А потому, что как только вы объявляете абстрактный метод в классе языка Java, этот класс автоматически становится абстрактным, а сделать абстрактный класс final’ьным в языке Java нельзя. Значит, абстрактных методов в final-классе Java быть не может.

final в языке Java нельзя.
Этот момент отделяет данный вопрос от более распространённого и часто задаваемого вопроса: можно ли в Java объявить класс абстрактным и финальным одновременно?
Рассмотрим один пример кода, чтобы продемонстрировать, что в final-классе невозможно объявить абстрактный метод. Пусть в Hello.java у нас есть public final класс под названием Hello, в котором есть абстрактный метод print().
public final class Hello {
public abstract void print();
}
Наберите этот код в IDE, вы получите следующее сообщение об ошибке, дескать Hello должен быть абстрактным классом, чтобы в нём можно было объявлять абстрактные методы.


final в Java нельзя, компилятор сгенерирует ошибку.
Это справедливо как для классов верхнего уровня, так и вложенных классов в языке Java. Даже если объявить абстрактный метод во вложенном final-классе, ошибка будет та же самая.
Еще один вытекающий отсюда вопрос: могут ли у абстрактного класса в языке Java быть статические методы?
Ответ: да, могут, никакой проблемы с объявлением статического метода в абстрактном классе нет, поскольку для использования статического метода не нужно создавать экземпляр класса, их можно вызывать просто при помощи имени класса.
Можно модифицировать наш пример, чтобы включить в класс Hello метод main(), являющийся в языке Java статическим, как показано ниже:
public abstract class Hello {
public abstract void print();
public static void main(String args[]) {
// какой-то код
}
}
Как вы можете видеть, никакой ошибки при компиляции не выдается. Этот код компилируется без проблем, поскольку в Java можно совершенно спокойно объявлять статический метод в абстрактном классе.
Краткие выводы
В final-классе невозможно объявить абстрактный метод. Потому что как только вы это сделаете, класс автоматически становится абстрактным, согласно спецификациям Java. А поскольку final-класс в Java не может быть абстрактным, это недопустимо, и компилятор запретит вам подобное действие, выдав ошибку. Но объявлять статические методы можно как в final, так и в абстрактных классах, никаких проблем с этим нет.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ