Extension Functions
https://kotlinlang.org/docs/extensions.html |
Extension Functions
Kotlin позволяет расширять класс или интерфейс новой функциональностью, не наследуясь от него и не используя шаблоны проектирования. Для того, чтобы объявить функцию-расширение, нужно указать в качестве префикса расширяемый тип. Расширения вычисляются статически. Расширения на самом деле не проводят никаких модификаций с классами, которые они расширяют. Объявляя расширение, вы создаёте новую функцию, а не новый член класса.
• как расширения поддерживаются функции и свойства.
• под капотом статическая функция Java, в качестве параметра - объект расширяемого типа.
val Int.toHexColor: String
get() = String.format("#%06X", 0xFFFFFF and this)
fun <T> MutableList<T>.swap(index1: Int, index2: Int) {
val tmp = this[index1]
this[index1] = this[index2]
this[index2] = tmp
}
interface IAction {
fun someA(): Int
fun someB(): Int
}
fun IAction.sum(): Int {
return someA() + someB()
}
Ограничения
• Не могут изменить поведение класса
Extension-функции не могут изменять внутреннее состояние класса или его поведение, они лишь добавляют новые методы. Все изменения доступны только на уровне использования функции и не влияют на сам класс.
// Не может изменить внутреннее состояние класса
fun String.isEmpty(): Boolean {
return this.length == 0
}
• Не могут быть заменены (override)
Extension-функции не могут переопределять методы класса. Они действуют как статические методы, которые “расширяют” класс, но не изменяют его фактическую реализацию.
open class Base {
open fun doSomething() {
println("Base")
}
}
fun Base.doSomething() {
println("Extension")
}
// Вызовет метод класса, а не extension-функцию
val base = Base()
base.doSomething() // Выведет "Base"
• Не могут изменять существующие методы
Extension-функции не могут изменять существующие методы класса или изменять их видимость. Они могут только добавить новые методы или функции, но не могут изменить поведение уже существующих.
// Можно только добавить новый метод
fun String.customMethod() {
println("Custom method")
}
// Не влияет на существующие методы String
"Hello".customMethod() // Выведет "Custom method"
• Не поддерживают полиморфизм
Extension-функции не поддерживают полиморфизм и не могут быть использованы для полиморфного вызова. Если в иерархии классов определены extension-функции, они не могут переопределяться в подклассах.
open class Animal
class Dog: Animal()
fun Animal.makeSound() {
println("Animal sound")
}
fun Dog.makeSound() {
println("Bark")
}
val animal: Animal = Dog()
animal.makeSound() // Выведет "Animal sound"
• Не могут быть вызваны через super
Extension-функции не могут быть вызваны через ключевое слово super, так как они не являются частью класса, а представляют собой статические методы.
open class Base {
open fun print() {
println("Base")
}
}
fun Base.print() {
println("Extension")
}
class Derived: Base() {
override fun print() {
super.print() // Вызовет метод Base, а не extension-функцию
}
}
• Не поддерживают доступ к private методам
Extension-функции не могут обращаться к private свойствам класса, к которому они относятся. Они могут взаимодействовать только с public членами класса.
class MyClass {
private fun privateMethod() {}
}
fun MyClass.accessPrivate() {
// Не может обратиться к privateMethod()
}
Kotlin Extension Functions. Вопросы на собесе
- Что такое extension-функции в Kotlin и зачем они нужны?
- Как extension-функции выглядят в Java?
- Какие ограничения есть у extension-функций?
- Что будет если сигнатура extension-функции совпадет с внутренней функцией класса?
Вызовется внутренняя функция, компилятор подсветит что имя занято.