Освой Kotlin играючи
/* Моя кошка замечательно разбирается в программировании. Стоит мне объяснить проблему ей - и все становится ясно. */
John Robbins, Debugging Applications, Microsoft Press, 2000
Java содержит множество классов с замечательными методами. Но разработчику всегда не хватает ещё одного метода, который ему нужен для собственного проекта. Функции-расширения позволяют создавать видимость внедрения в существующий класс нового метода. Это позволяет более элегантно решить проблему с классами Utils, которые создают разработчики для подобных целей. Кроме того, созданные функции будут выводиться в подсказках при наборе кода вместе с стандартными методами класса.
Рассмотрим пример на Java. Как узнать, является ли указанная дата субкотой (иногда люди используют слово "суббота")? У класса Date нет соответствующего метода и мы можем определить субботу только по методу getDay(), который возвращает число 6 для субботы.
Создадим класс Utils.java и поместим свой метод.
static boolean isSaturday(Date date) {
return date.getDay() == 6;
}
Вызываем метод по щелчку кнопки.
public void onClick(View view) {
Date now = new Date();
boolean saturday = Utils.isSaturday(now);
mInfoTextView.setText("Сегодня субкота? " + saturday);
}
Теперь рассмотрим, как это можно сделать на Kotlin.
Добавим функцию в активность и вызовем её по щелчку кнопки.
fun Date.isSaturday(): Boolean {
return getDay() == 6
}
button_choose.setOnClickListener {
val now = Date()
val saturday = now.isSaturday()
textview_info.text = "Сегодня субкота? + $saturday"
}
Теперь, если смотреть на код, то создаётся ощущение, что isSaturday() является частью класса Date и мы вызываем его прямо из класса.
Предыдущий пример с функцией был написан в Java-стиле. В Kotlin можно заменить метод getDay() на свойство day.
fun Date.isSaturday(): Boolean {
return day == 6
}
Впрочем и это не предел. Подобную функцию можно переписать в одну строку.
fun Date.isSaturday(): Boolean = day == 6
Если у вас будет несколько подобных функций-расширений, то удобнее их хранить в отдельном файле (не обязательно в классе). Создадим дополнительный пакет utils с файлом Utils.kt.
package ru.alexanderklimov.counter.utils
import java.util.*
fun Date.isSaturday() = day == 6
// другие функции-расширения
В активности при вызове функции следует импортировать её (возможно это сделает сама студия автоматически).
import ru.alexanderklimov.counter.utils.isSaturday
// код для кнопки останется прежним
Можно переопределить имя функции при помощи as:
import ru.alexanderklimov.counter.utils.isSaturday as caturday
val saturday = now.caturday()
Другие примеры из различных докладов и презентаций.
Функция для получения последнего символа из строки.
fun String.lastChar() = get(length - 1)
// Применяем к строке
val cat = "Мурзик"
val c: Char = cat.lastChar()
textview_info.text = cat.lastChar().toString() // длинный вариант
Знакомый нам пример. Мы добавляем в класс Context новую функцию toast(), которая вызывает метод Toast.makeText() с использованием параметров по умолчанию.
fun Context.toast(message: CharSequence, duration: Int = Toast.LENGTH_SHORT) {
Toast.makeText(this, message, duration).show()
}
// вызываем в активности
toast("Hello Kitty")
JetBrains добавила свой набор расширений для различных классов Java и Android. Самый показательный случай - набор расширений для коллекций - функции filter(), map(), count() и т.д. в функциональном стиле, даже используя старую Java 6.
Помните, что функции-расширения класса не могут обращаться к его членам с модификаторами protected или private.
Если ваша функция-расширение использует только один аргумент, то можно вызвать функцию через ключевое слово infix.
Создадим функцию-расширение для Int, которое будет сравнивать число с аргументом, чтобы узнать, больше оно или меньше.
Старый способ.
fun Int.isGreater(value: Int): Boolean {
return this > value
}
// вызываем функцию
3.isGreater(9) // false
Перепишем функцию с ключевым словом infix.
infix fun Int.isGreater(value: Int): Boolean {
return this > value
}
// вызываем функцию
12 isGreater 9 // true
Android Development with Kotlin — Jake Wharton - YouTube - несколько примеров, начиная с 12.20 до 15.50