У цій статті ви дізнаєтесь про інтерфейси та про те, як це реалізувати в Kotlin за допомогою прикладів.
Інтерфейси Kotlin подібні до інтерфейсів у Java 8. Вони можуть містити визначення абстрактних методів, а також реалізації не абстрактних методів. Однак вони не можуть містити жодного стану.
Це означає, що інтерфейс може мати властивість, але він повинен бути абстрактним або повинен забезпечувати реалізації доступу.
Рекомендована література: Абстрактний клас Котліна
Абстрактні класи в Kotlin подібні до інтерфейсу з однією важливою відмінністю. Не обов’язково, щоб властивості абстрактного класу були абстрактними або забезпечували реалізації доступу.
Як визначити інтерфейс?
Ключове слово interface
використовується для визначення інтерфейсів у Kotlin. Наприклад,
інтерфейс MyInterface (var test: String // абстрактна властивість fun foo () // абстрактний метод fun hello () = "Hello there" // метод із реалізацією за замовчуванням)
Ось,
- створюється інтерфейс MyInterface.
- інтерфейс має абстрактний тест властивостей та абстрактний метод
foo()
. - інтерфейс також має не абстрактний метод
hello()
.
Як реалізувати інтерфейс?
Ось як клас або об’єкт можуть реалізувати інтерфейс:
інтерфейс MyInterface (тест тесту: int // абстрактна властивість fun foo (): String // абстрактний метод (повертає String) fun hello () (// метод із реалізацією за замовчуванням // тіло (необов’язково))) клас InterfaceImp: MyInterface (override тест тесту val: Int = 25 перевизначити fun foo () = "Lol" // інший код)
Тут клас InterfaceImp реалізує інтерфейс MyInterface.
Клас замінює абстрактні члени (властивість тесту та foo()
метод) інтерфейсу.
Приклад: Як працює інтерфейс?
interface MyInterface ( val test: Int fun foo() : String fun hello() ( println("Hello there, pal!") ) ) class InterfaceImp : MyInterface ( override val test: Int = 25 override fun foo() = "Lol" ) fun main(args: Array) ( val obj = InterfaceImp() println("test = $(obj.test)") print("Calling hello(): ") obj.hello() print("Calling and printing foo(): ") println(obj.foo()) )
Коли ви запускаєте програму, результат буде:
test = 25 Виклик привіт (): Привіт, приятелю! Виклик та друк foo (): Lol
Як зазначалося вище, інтерфейс може також мати властивість, що забезпечує реалізацію доступу. Наприклад,
interface MyInterface ( // property with implementation val prop: Int get() = 23 ) class InterfaceImp : MyInterface ( // class body ) fun main(args: Array) ( val obj = InterfaceImp() println(obj.prop) )
Коли ви запускаєте програму, результат буде:
23
Тут опора не є абстрактною. Однак він дійсний всередині інтерфейсу, оскільки забезпечує реалізацію для доступу.
Однак ви не можете зробити щось на зразок val prop: Int = 23
усередині інтерфейсу.
Реалізація двох або більше інтерфейсів у класі
Котлін не допускає справжнього багаторазового успадкування. Однак можливо реалізувати два або більше інтерфейсів в одному класі. Наприклад,
interface A ( fun callMe() ( println("From interface A") ) ) interface B ( fun callMeToo() ( println("From interface B") ) ) // implements two interfaces A and B class Child: A, B fun main(args: Array) ( val obj = Child() obj.callMe() obj.callMeToo() )
Коли ви запускаєте програму, результат буде:
З інтерфейсу A З інтерфейсу B
Вирішення основних конфліктів (множинні інтерфейси)
Припустимо, два інтерфейси (A і B) мають не абстрактний метод з однаковою назвою (скажімо, callMe()
метод). Ви реалізували ці два інтерфейси в класі (скажімо, С). Тепер, якщо ви викликаєте callMe()
метод за допомогою об'єкта класу C, компілятор видасть помилку. Наприклад,
interface A ( fun callMe() ( println("From interface A") ) ) interface B ( fun callMe() ( println("From interface B") ) ) class Child: A, B fun main(args: Array) ( val obj = Child() obj.callMe() )
Ось помилка:
Помилка: (14, 1) Kotlin: Клас 'C' повинен замінити загальнодоступний відкритий розважальний викликMe (): Одиниця, визначена в A, оскільки вона успадковує кілька її інтерфейсних методів
Щоб вирішити цю проблему, вам слід надати власну реалізацію. Ось як:
interface A ( fun callMe() ( println("From interface A") ) ) interface B ( fun callMe() ( println("From interface B") ) ) class C: A, B ( override fun callMe() ( super.callMe() super.callMe() ) ) fun main(args: Array) ( val obj = C() obj.callMe() )
Тепер, коли ви запускаєте програму, результат буде таким:
З інтерфейсу A З інтерфейсу B
Тут явна реалізація callMe()
методу передбачена в класі C.
клас C: A, B (перевизначити веселий callMe () (super.callMe () super .callMe ()))
Оператор super.callMe()
викликає callMe()
метод класу А. Аналогічно, викликає метод класу .super.callMe()
callMe()
B