Интерфейсы Kotlin

Интерфейсы Kotlin похожи на интерфейсы Java 8. Ключевое слово interface используется для определения интерфейсов, позволяя методам иметь реализации по умолчанию:

interface MyInterface { fun bar() //Не реализовано fun foo() { //Реализовано //Необязательное тело метода println("foo") } }

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

Класс или объект может реализовывать один или несколько интерфейсов.

class Child : MyInterface { override fun bar() { //Тело метода } }

Пример

interface MyInterface { fun bar() fun foo() { //Необязательное тело метода println("foo") } } class Child : MyInterface { override fun bar() { //Тело метода println("bar") } } fun main(args: Array<String>) { val c = Child() c.foo(); c.bar(); }

Результат вывода:

foo
bar

Свойства в интерфейсах

Свойства в интерфейсах могут быть только абстрактными; инициализирующие значения не допускаются. Интерфейсы не хранят значения свойств. При реализации интерфейса свойства должны быть переопределены:

interface MyInterface{ var name:String //свойство name, абстрактное } class MyImpl:MyInterface{ override var name: String = "example" //Переопределение свойства }

Пример

interface MyInterface { var name:String //свойство name, абстрактное fun bar() fun foo() { //Необязательное тело метода println("foo") } } class Child : MyInterface { override var name: String = "example" //Переопределение свойства override fun bar() { //Тело метода println("bar") } } fun main(args: Array<String>) { val c = Child() c.foo(); c.bar(); println(c.name) }

Результат вывода:

foo
bar
example

Переопределение функций

При реализации нескольких интерфейсов вы можете столкнуться с проблемой наследования нескольких реализаций одного и того же метода. Например:

Пример

interface A { fun foo() { print("A") } //Реализовано fun bar() //Не реализовано, нет тела метода, абстрактный } interface B { fun foo() { print("B") } //Реализовано fun bar() { print("bar") } //Реализовано } class C : A { override fun bar() { print("bar") } //Переопределение } class D : A, B { override fun foo() { super<A>.foo() super<B>.foo() } override fun bar() { super<B>.bar() } } fun main(args: Array<String>) { val d = D() d.foo(); d.bar(); }

Результат вывода:

ABbar

В примере интерфейсы A и B оба определяют методы foo() и bar(). Оба реализуют foo(), а B реализует bar(). Поскольку C — конкретный класс, реализующий A, он должен переопределить bar() и реализовать этот абстрактный метод.

Однако если мы наследуем D от A и B, нам нужно реализовать все методы, унаследованные от нескольких интерфейсов, и указать, как D должен их реализовывать. Это правило применяется как к методам, которые наследуют единственную реализацию (bar()), так и к методам, которые наследуют несколько реализаций (foo()).

Другие расширения