Ответ
Функции расширения (extension functions) в Kotlin позволяют добавлять новые функции к существующим классам без наследования или модификации исходного кода. Они объявляются с префиксом имени класса, который расширяется.
// Пример: расширение класса String
fun String.addExclamation(): String {
return "$this!"
}
// Использование
val greeting = "Hello".addExclamation() // "Hello!"
Особенности:
- Не изменяют оригинальный класс
- Доступны как обычные методы класса
- Работают с nullable-типами (
String?.) - Можно расширять даже классы из стандартной библиотеки или Java-классы
Ответ 18+ 🔞
А, ну слушай, вот эта штука с extension functions — это вообще пиздец как удобно, я тебе скажу. Представь, что ты купил машину, а потом тебе говорят: «А хочешь, мы тебе к ней прикрутим ништяк, чтобы она ещё и кофе варила?» И ты такой: «Ну хули нет». И вот тебе уже не надо новую машину покупать, просто приварили кофеварку к капоту, и всё, едешь и капучино себе на ходу делаешь. Примерно так это и работает.
Вот смотри, есть у тебя класс, например, String. Стандартный, из коробки. И вдруг тебе позарез понадобилось, чтобы у каждой строки был метод, который добавляет к ней восклицательный знак. Раньше пришлось бы городить какой-нибудь утилитарный класс StringUtils и писать там статический метод addExclamation(String s). А потом везде его импортить и вызывать. Скучно, неудобно, выглядит как говно.
А теперь можно сделать так, ёпта:
// Просто берёшь и говоришь: "А пусть у всех String'ов будет такой метод!"
fun String.addExclamation(): String {
return "$this!" // this — это та самая строка, у которой метод вызвали
}
// Использование
val greeting = "Hello".addExclamation() // Получится "Hello!"
Вот и всё, блядь. Теперь у любой строки в твоём коде, в этом файле, есть метод addExclamation(). Вызываешь его, как будто он там всегда и был. Красота, да? Удивление пиздец просто.
Ну и какие там фишки, на что смотреть:
- Не лезут в чужой огород. Они реально не меняют исходный класс. Никакого наследования, никакой магии с байткодом. Это просто синтаксический сахар, который компилятор разворачивает в тот самый статический вызов. Но выглядит-то как родной метод! Хитрая жопа, но гениальная.
- Доступны как свои. После объявления расширения ты можешь звать этот метод ровно так же, как и все остальные методы этого класса. IDE будет его подсказывать, автодополнение работать — красота.
- Работают даже с nullable. Вот это вообще мощь. Можешь объявить расширение для
String?. И внутри функции уже проверять: еслиthis == null, то возвращать что-то одно, а если не null — другое. Удобно для всяких преобразований или безопасных операций. - Расширяй кого хочешь. Да хоть
ArrayListиз Java, хотьThread, хоть какой-нибудь легаси-класс из древней библиотеки. Не надо ждать, пока автор класса что-то добавит. Сам себе царь, сам себе добавляешь функционал. Главное — не переборщить, а то получится такой зоопарк, что потом сам от себя охуеешь.
Короче, вещь архиполезная. Поначалу кажется, что какая-то ерунда, но как втянешься — начинаешь везде их пихать. Только без фанатизма, а то можно такую мудню нарасширять, что потом разбираться будет страшнее, чем в дебрях чужого кода.