Sobes.tech
Junior

Чӣ гуна мерос ва полиморфизм дар Kotlin ташкил шудааст?

sobes.tech AI

Ҷавоб аз AI

В Kotlin наследяването се реализира чрез механизма на класове и интерфейси. Класовете могат да наследяват само един друг клас (единично наследяване), но могат да реализират множество интерфейси.

По подразбиране всички класове в Kotlin са 'финални', тоест не могат да бъдат наследени. За да се разреши наследяване, класът трябва да бъде явно обозначен с ключовата дума open.

Наследяване на класове:

open class Shape { // Основен клас, обозначен като open
    open fun draw() { // Метод, който може да бъде преписан
        println("Drawing a shape")
    }
}

class Circle : Shape() { // Наследяване от Shape
    override fun draw() { // Презаписване на метода
        println("Drawing a circle")
    }
}

В конструктора на наследения клас трябва да се извика конструкторът на базовия клас, явно или неявно.

Интерфейси:

Интерфейсите в Kotlin са подобни на тези в Java 8 и могат да съдържат абстрактни методи и реализирани методи с тяло. Класовете могат да реализират един или повече интерfeйси.

interface Drawable {
    fun draw() // Абстрактен метод
    fun description() { // Метод с подразбираща се реализация
        println("This is a drawable object")
    }
}

class Square : Drawable {
    override fun draw() { // Реализация на абстрактния метод
        println("Drawing a square")
    }
    // description() може да бъде преписана, но не е задължително
}

Полиморфизъм:

Полиморфизмът в Kotlin се постига чрез възможността да работите с обекти от различни класове чрез общ базов тип (класа или интерfeйса). Това позволява да се извикват методи, специфични за конкретния тип обект, по време на изпълнение.

fun render(drawable: Drawable) {
    drawable.draw() // Извикване на метода draw() в зависимост от фактическия тип на обекта
    drawable.description()
}

fun main() {
    val circle: Shape = Circle() // Обект Circle се разглежда като Shape
    circle.draw() // Извикване на draw() от Circle поради полиморфизма

    val square: Drawable = Square() // Обект Square се разглежда като Drawable
    render(square) // Извикване на draw() и description() от Square
}

В този пример render работи с всеки обект, реализиращ Drawable. Извикването drawable.draw() ще изпълни реализацията на метода draw за конкретния тип обект (Square в този случай).

Разлика между наследяването на класове и реализирането на интерфейси:

  • Наследяване на клас: Определя отношението "е" (is-a). Подкласът наследява състоянието и поведението на базовия клас.
  • Реализиране на интерфейс: Определя "способност" или "сделка". Класът обещава да предостави реализация за всички абстрактни методи на интерфейса.

Таблица за сравнение:

Характеристика Наследяване на клас Реализация на интерфейс
Тип връзка is-a Способност / Сделка
Многократност Еднопосочно Многократна
Състояние Наследява състоянието на базовия клас Не наследява състояние
Реализация на методи Може да съдържа реализация Може да съдържа подразбираща се (от Java 8)