Освой Kotlin играючи

Сайт Александра Климова

Шкодим

/* Моя кошка замечательно разбирается в программировании. Стоит мне объяснить проблему ей - и все становится ясно. */
John Robbins, Debugging Applications, Microsoft Press, 2000

Интерфейсы

Интерфейсы в Kotlin ближе к Java 8 и имеют свои особенности. Например, интерфейсы могут содержать объявления свойств.

Класс интерфейса может содержать абстрактные и конкретные функции. Если функция не содержит тела, то она является абстрактной и помечать её как abstract нет необходимости. Если функция конкретная, то как обычно добавляем тело после фигурных скобок.

Объявим интерфейс с одним абстрактным методом.


interface Clickable
{ 
    fun click()
}

Реализация интерфейса в классе.


class Button : Clickable {
    override fun click() = println("I was clicked")
}

Двоеточие после имени класса заменяет ключевые слова implements и extends.

Ключевое слово override используется вместо аннотации @Override и является обязательным, что снижает количество потенциальных ошибок при неправильном использовании.

У интерфейса можно задать значения по умолчанию. Если в Java 8 для этих целей используется ключевое слово default, то в Kotlin просто указываете тело метода. Добавим в интерфейс ещё один метод, использующий значение по умолчанию.


interface Clickable
{ 
    fun click()
    fun meow() = println("Я мяукаю!")
}

Если вас устраивает значение по умолчанию, то реализовывать его в классе не нужно. Либо вы можете изменить поведение метода вместе с click().

Возможна ситуация, когда два разных интерфейса используют одно и то же имя для метода. В этом случае вам придётся их явно реализовывать, даже если их значения по умолчанию вас устраивают.

Добавим ещё один интерфейс.


interface Focusable {
    fun setFocus(b: Boolean) =
            println("I ${if (b) "got" else "lost"} focus.")
    fun meow() = println("В фокусе я рычу. Р-р-р!")
}

class Button : Clickable, Focusable {
    override fun click() = println("I was clicked")
    override fun meow() {
        super<Clickable>.meow()
        super<Focusable>.meow()
    }
}

Если нужно вызвать только одну унаследованную реализацию, то можете поступить следующим образом.


override fun meow() = super<Clickable>.meow()

Вызываем методы.


val button = Button()
button.meow()
button.setFocus(true)
button.click()

Получим следующее.


Я мяукаю!
В фокусе я рычу. Р-р-р!
I got focus.
I was clicked

Мы вызвали метод meow() один раз, но отработало два раза, так как такой метод встречается в двух интерфейсах.

Можно добавлять в интерфейс абстрактные свойства без указания abstract. Свойствам нельзя присвоить значение и инициализировать.


interface Roamable {
	val velocity: Int
}

Можем задать геттер, но его можно переопределить в классе, который будет использовать интерфейс.


interface Roamable {
	val velocity: Int
	    get() = 10
}
Реклама