Ответ
Абстрактный класс — это класс, который нельзя инстанцировать напрямую. Он служит шаблоном для других классов и может содержать как абстрактные методы (без реализации), так и обычные методы с реализацией.
Ключевые особенности:
- Может иметь абстрактные методы (обязательные для переопределения в наследниках).
- Может содержать реализованные методы.
- Позволяет выносить общую логику в базовый класс.
Пример:
abstract class Animal {
abstract fun makeSound() // Абстрактный метод
fun eat() { println("Eating...") } // Обычный метод
}
class Dog : Animal() {
override fun makeSound() { println("Bark!") }
}
Отличие от интерфейса:
- Абстрактный класс может хранить состояние (поля), интерфейс — нет (до Kotlin 1.4).
- Класс может наследовать только один абстрактный класс, но много интерфейсов.
Ответ 18+ 🔞
Давай разберём, что за зверь такой — абстрактный класс. Представь себе чертёж, шаблон, болванку. Ты не можешь взять этот чертёж и сказать: «Вот он, готовый продукт!». Нет, ёпта, это просто инструкция, по которой другие классы должны отливаться. Сам по себе он — пустышка, инстанцировать его напрямую — нихуя не выйдет. Он существует, чтобы его наследники не были распиздяями и знали, что от них требуется.
Что он умеет, эта мартышлюшка:
- Может объявлять абстрактные методы — это как приказ с большой буквы: «Наследник, переопредели меня, а то нихуя не заработает!». Реализации там ноль, только название и требование.
- Но при этом он не идиот — может содержать и обычные, уже готовые методы, с реализацией. Чтобы каждый раз одно и то же не писать в каждом классе-наследнике.
- Главная фишка — вынести всю общую, повторяющуюся хуйню в одно место, чтобы не копипастить код, как последний лентяй.
Смотри, как это выглядит на практике:
abstract class Animal {
abstract fun makeSound() // Абстрактный метод. Типа, "гавкай" или "мяукай", а как — твои проблемы.
fun eat() { println("Eating...") } // А вот это обычный метод. Все жрут одинаково, тут уже всё за тебя сделали.
}
class Dog : Animal() {
override fun makeSound() { println("Bark!") } // А вот здесь уже обязанность. Переопределили и ладно.
}
А теперь главное: чем он отличается от интерфейса? А то все путают, волнение ебать.
- Состояние. Абстрактный класс — он как серьёзный дядя, может хранить в себе поля, состояние. А интерфейс (до определённых версий Kotlin) был как принципиальный философ — только контракты, только поведение, никаких данных.
- Наследование. Тут жёстко: класс может унаследоваться только от одного абстрактного класса. Как от одного отца. А вот интерфейсов много можно прицепить. Как курсы повышения квалификации — хоть все сразу. Так что выбирай, что тебе нужнее: мощное единое ядро от одного предка или куча разных умений от разных интерфейсов.
Короче, абстрактный класс — это когда тебе нужен не просто список требований (как в интерфейсе), а уже какая-то готовая база, фундамент с кое-какой логикой внутри, от которого все будут плясать.