Kotlin в IntelliJ IDEA Kotlin змінні Kotlin типи даних Kotlin операції з числами Kotlin умовні вирази Kotlin умовні конструкції Kotlin цикли Kotlin послідовності Kotlin масиви Kotlin функціональне програмування Kotlin змінна кількість параметрів. Vararg Kotlin повернення результату. оператор return Kotlin однорядкові і локальні функції Kotlin перевантаження функцій Kotlin Лямбда-вирази Kotlin функції вищого порядку Kotlin Анонімні функції Kotlin ООП Класи і об'єкти Kotlin ООП властивості Kotlin ООП конструктор Kotlin ООП функції в класах Kotlin ООП Пакети та імпорт Kotlin ООП модифікатори видимості Kotlin ООП вкладені класи Kotlin ООП інтерфейси Kotlin ООП спадкування Kotlin ООП Перевизначення методів і властивостей Kotlin ООП Абстрактні класи та методи Kotlin ООП Data-класи Kotlin ООП перерахування enums Kotlin ООП Null і nullable-типи Kotlin ООП Обробка винятків Kotlin ООП перетворення типів Kotlin ООП Інфіксна функція Kotlin ООП функції розширення Kotlin ООП Узагальнені класи і функції Kotlin ООП обмеження узагальнень Kotlin ООП Варіантність, коваріантність і контраваріантність Kotlin Колекції. Змінювані і незмінні колекції Kotlin Колекції. LIST список Kotlin Колекції. Set Kotlin Колекції. Map

Kotlin ООП Перевизначення методів і властивостей


перевизначення методів

Kotlin дозволяє перевизначати функції, визначені в базовому класі. Щоб функції базового класу можна було перевизначити, до них застосовується анотація open . При перевизначенні в похідному класі до цих функцій застосовується анотація override :

open class Person(val name: String){
    open fun display(){
        println("Name: $name")
    }
}
class Employee(val company: String, name: String): Person(name){
 
    override fun display() {
        println("Name: $name    Company: $company")
    }
}

Функція display визначена в класі Person з анотацією open , тому в похідних класах його можна перевизначити. У класі Employee ця функція перевизначена із застосуванням анотації override .

Варто враховувати, що перевизначити функції можна по всій ієрархії успадкування. Наприклад, у нас може бути клас Manager, успадкований від Employee:

open class Person(val name: String){
    open fun display(){
        println("Name: $name")
    }
}
open class Employee(val company: String, name: String): Person(name){
 
    override fun display() {
        println("Name: $name    Company: $company")
    }
}
class Manager(company: String, name: String):Employee(company, name){
    override fun display() {
        println("Name: $name Company: $company  Position: Manager")
    }
}

В даному випадку клас Manager переопределяет функцію display, оскільки серед його базових класів є клас Person, який визначає цю функцію. В цей же час іноді буває необхідно заборонити подальше перевизначення функції в класах-спадкоємців. Для цього застосовується ключове слово final :

open class Person(val name: String){
    open fun display(){
        println("Name: $name")
    }
}
open class Employee(val company: String, name: String): Person(name){
 
    final override fun display() {
        println("Name: $name    Company: $company")
    }
}
class Manager(company: String, name: String):Employee(company, name){
    // теперь функцию нельзя переопределить
    /*override fun display() {
        println("Name: $name Company: $company  Position: Manager")
    }*/
}

перевизначення властивостей

Властивості перевизначаються також як і функції за допомогою ключового слова override . Щоб зробити властивість доступним для перевизначення в базовому класі воно також оголошується з анотацією open :

open class Person(val name: String){
 
    open val fullInfo: String
        get() = "Name: $name"
}
open class Employee(val company: String, name: String): Person(name){
 
    override val fullInfo: String
        get() = "Name: $name  Company: $company"
}

Звернення до реалізації з базового класу

За допомогою ключового слова super в похідному класі можна звертатися до реалізації з базового класу.

open class Person(val name: String){
 
    open val fullInfo: String
        get() = "Name: $name"
 
    open fun display(){
        println("Name: $name")
    }
}
open class Employee(val company: String, name: String): Person(name){
 
    override val fullInfo: String
        get() = "${super.fullInfo} Company: $company"
 
    final override fun display() {
        super.display()
        println("Company: $company")
    }
}

В даному випадку похідний клас Employee при перевизначенні властивості і функції застосовує реалізацію з базового класу Person. Наприклад, через super.fullInfo повертається значення властивості з базового класу (тобто значення властивості name), а за допомогою виклику super.display() викликається реалізація функції display з класу Person.


Правила перевизначення

У Kotlin ми можемо наслідувати клас і застосовувати інтерфейси. При цьому ми можемо одночасно і успадковуватися від класу, і застосовувати один або кілька інтерфейсів. Однак що, якщо переобумовленої функція з базового класу має те ж ім'я, що і функція з застосовуваного інтерфейсу:

open class Video {
    open fun play() { println("Play video") }
}
 
interface AudioPlayable {
    fun play() { println("Play audio") }
}
 
class MediaPlayer() : Video(), AudioPlayable {
    // Функцию play обязательно надо переопределить
    override fun play() {
        super<Video>.play()         // вызываем Video.play()
        super<AudioPlayable>.play() // вызываем AudioPlayable.play()
    }
}

Тут клас Video і інтерфейс AudioPlayable визначають функцію play. В цьому випадку клас MediaPlayer, який успадковується від Video і застосовує інтерфейс AudioPlayable, обов'язково повинен визначити функцію з тим же ім'ям, тобто play. За допомогою конструкції super<имя_типа>.имя_функции можна звернутися до опредленія реалізації або з базового класу, або з інтерфейсу.


Наш партнер:
beta test mp3 playlist downloader