Интерфейсы играют роль требования к классу. Все обязательные члены в интерфейсе
В интерфейсах описывается сигнатура функций или свойств, которые затем класс применяющий интерфейс по необходимости должен переписать, используя ключевое слово override.
В интерфейсах функции могут быть абстрактными (не иметь тела) или иметь код, который выполняется если в классе функция не переписана.
Свойства в интерфейсах либо должны быть абстрактными, либо для них должны быть определены функции доступа (getter и setter). В отличии от классов в свойствах в интерфейсах нет доступа к его значению посредством ключевого слова field.
interface MyInterface {
// Для обычных переменных указывается только название и тип
var prop : Int
// Можно указать значение, если переменная только для чтения
val prop2 : String get() = "Property 2"
// Абстрактная функция не имеет тела
fun test()
// Абстрактная функция принимающая аргументы и которая должна вернуть значение типа String
fun test(param : String, param2 : Int) : String
// Код функции выполняется когда эта функция не переписана в классе.
fun second() {
println("Function code is not written")
}
}
Если класс применяет только интерфейс и не наследует другой класс, тогда название интерфейса пишется через двоеточие - :, когда класс применяет более одного интерфейса или также является производным классом наряду с применением интерфейса тогда разделителем является запятая.
Когда класс применяет интерфейс все обязательные для имплементации методы должны быть переписаны в классе:
class MainActivity : AppCompatActivity(), MyInterface {
// Переписывание свойства из примененного интерфейса
override var prop: Int = 0
get() = field
set(value) {
field = value
}
// Код для выполнения при вызове функции test, так как функция не имеет поведение по умолчанию
override fun test() {}
// Код перегруженной версии функции test, которая принимает два параметра и возвращает результат строкового типа
override fun test(param: String, param2: Int): String {
return "Test"
}
// Переписывание функции second необязательна так как она имеет поведение по умолчанию, но по необходимости можно переписать
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
}
Один интерфейс может наследовать другой и в наследуемом интерфейсе члены родительского интерфейса также становятся доступны, ровно так же как и в процессе наследования классов. Класс применяемый подобный интерфейс должен переписать все обязательные функции во всей цепочке наследования интерфейсов.
В случае добавления ещё одного интерфейса в наш пример со свойством isActive, который наследует интерфейс MyInterface и применить его, то в данном случае в классе необходимо переписать как обязательные члены первого интерфейса, так и второго, так как второму они становятся доступны "по наследству":
interface SecondInterface : MyInterface {
var isActive : Boolean
}
class MainActivity : AppCompatActivity(), SecondInterface {
override var isActive: Boolean = false
// Переписывание свойства из примененного интерфейса
override var prop: Int = 0
get() = field
set(value) {
field = value
}
// Код для выполнения при вызове функции test, так как функция не имеет поведение по умолчанию
override fun test() {}
// Код перегруженной версии функции test, которая принимает два параметра и возвращает результат строкового типа
override fun test(param: String, param2: Int): String {
return ""
}
// Переписывание функции second необязательна так как она имеет поведение по умолчанию
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
}
Реклама