Функция расширения Kotlin предоставляет возможность «добавлять» методы в класс без наследования класса или использования какого-либо шаблона проектирования. Созданные функции расширения используются как обычные функции внутри этого класса.
Функция расширения объявляется с префиксом типа получателя с именем метода.
fun <class_name>.<method_name>()
В приведенном выше объявлении <class_name> является типом получателя, а <method_name>() является функцией расширения.
Пример объявления функции расширения и ее использование
Как правило, мы вызываем все методы извне класса, которые уже определены внутри класса. В приведенном ниже примере класс Student объявляет метод Passed(), который вызывается из функции main() путем создания объекта student класса Student.
Предположим, что мы хотим вызвать метод (скажем, isExcellent()) класса Student, который не определен в классе. В такой ситуации мы создаем функцию(isExcellent()) вне класса Student как Student.isExcellent() и вызываем ее из функции main(). Функция объявления Student.isExcellent() известна как функция расширения, где класс Student известен как тип получателя.
class Student{
fun isPassed(mark: Int): Boolean{
return mark>40
}
}
fun Student.isExcellent(mark: Int): Boolean{
return mark > 90
}
fun main(args: Array){
val student = Student()
val passingStatus = student.isPassed(55)
println("student passing status is $passingStatus")
val excellentStatus = student.isExcellent(95)
println("student excellent status is $excellentStatus")
}
Выход:
student passing status is true student excellent status is true
Приведенный выше пример демонстрирует только то, как объявить функцию расширения.
Пример функции расширения Kotlin
Давайте посмотрим на реальный пример функции расширения в Котлин. В этом примере мы меняем местами элементы MutableList, используя метод swap(). Однако класс MutableList не предоставляет внутреннего метода swap(), который меняет местами его элементы. Для этого мы создаем функцию расширения для MutableList с функцией swap().
Объект списка вызывает функцию расширения(MutableList.swap(index1: Int, index2: Int):MutableList), используя вызов функции list.swap(0,2). Функция swap(0,2) передает значение индекса списка внутри MutableList.swap(index1: Int, index2: Int):MutableList) sxtension.
fun MutableList.swap(index1: Int, index2: Int):MutableList {
val tmp = this[index1] // 'this' represents to the list
this[index1] = this[index2]
this[index2] = tmp
return this
}
fun main(args: Array) {
val list = mutableListOf(5,10,15)
println("before swapping the list :$list")
val result = list.swap(0, 2)
println("after swapping the list :$result")
}
Выход:
before swapping the list :[5, 10, 15] after swapping the list :[15, 10, 5]
Функция расширения как получатель, допускающий значение Nullable
Функция расширения может быть определена как тип получателя, допускающий значение NULL. Эта функция расширения, допускающая значение NULL, вызывается через переменную объекта, даже если значение объекта равно NULL. Обнуляемость объекта проверяется с помощью этого == null внутри тела.
Давайте перепишем приведенную выше программу, используя функцию расширения в качестве получателя, допускающего значение NULL.
funMutableList?.swap(index1: Int, index2: Int): Any {
if(this == null) return "null"
else {
val tmp = this[index1] // 'this' represents to the list
this[index1] = this[index2]
this[index2] = tmp
return this
}
}
fun main(args: Array) {
val list = mutableListOf(5,10,15)
println("before swapping the list :$list")
val result = list.swap(0, 2)
println("after swapping the list :$result")
}
Выход:
before swapping the list :[5, 10, 15] after swapping the list :[15, 10, 5]
Расширения сопутствующих объектов
Объект-компаньон — это объект, который объявлен внутри класса и помечен ключевым словом компаньона. Сопутствующий объект используется для вызова функции-члена класса напрямую с использованием имени класса(например, static в java).
Класс, который содержит объект-компаньон, также может быть определен как функция расширения и свойство для объекта-компаньона.
Пример companion object
В этом примере мы вызываем функцию create(), объявленную внутри объекта-компаньона, используя имя класса(MyClass) в качестве квалификатора.
class MyClass {
companion object {
fun create():String{
return "calls create method of companion object"
}
}
}
fun main(args: Array){
val instance = MyClass.create()
}
Выход:
calls create method of companion object
Пример расширения объекта-компаньона
Давайте посмотрим на пример расширения объекта-компаньона. Расширение объекта-компаньона также вызывается с использованием имени класса в качестве квалификатора.
class MyClass {
companion object {
fun create(): String {
return "calling create method of companion object"
}
}
}
fun MyClass.Companion.helloWorld() {
println("executing extension of companion object")
}
fun main(args: Array) {
MyClass.helloWorld() //extension function declared upon the companion object
}
Выход:
executing extension of companion object
