Kotlin Là Gì?
Kotlin Là Gì?

OOP Mastery: Tính đa hình – Polymorphism trong Kotlin

OOP Mastery là chuỗi bài viết tự học Lập trình hướng đối tượng với ngôn ngữ Kotlin được biên soạn tại DanTech0xFF. Mục đích của chuỗi bài viết này là cung cấp cái nhìn toàn diện về Hướng đối tượng trong ngôn ngữ Kotlin. Đây sẽ là nền tảng vững chắc cho Lập trình viên trong tương lai nếu các bạn đi sâu về mảng Android, Mobile Cross Platform, hoặc Backend Java.

Trong bài viết này chúng ta sẽ phân tích Tính Đa hình của OOP trong ngôn ngữ lập trình Kotlin.

Nhắc lại tính đa hình

Tính đa hình – Polymorphism trong OOP thể hiện qua việc các Class khác nhau, kế thừa chung 1 Class, Interface có thể cùng gọi đến 1 hàm (thuật ngữ gọi là cùng giao diện/Interface) nhưng lại có thể thực hiện các Logic khác nhau tùy vào từng nơi khai báo.

Hiểu đơn giản là Đa hình – cùng 1 hình thức nhưng nội dung bên trong khác nhau.

Polymorphism trong Kotlin

Overload

Overload là việc định nghĩa các phương thức (hàm) trong Class có cùng tên nhưng khác nhau về các input params

interface Encryptor {
  fun encrypt(input: String): String
  fun encrypt(input: Int): Int
  fun encrypt(input: Char): Char
}

Override

Override: Định nghĩa các phương thức (hàm) trong Class con được kế thừa từ Class cha, và thay đổi hoàn toàn logic bên trong nó.

  • Override với open class
open class BaseClass {
    open var name: String = "BaseClass"
    open fun print() {
        println("Hello from BaseClass1")
    }
}

class SubClass : BaseClass() {
    override var name: String = "SubClass" // kotlin cho phép bạn override properties
        get() = super.name
        set(value) {
            field = value
        }
    override fun print() {
        super.print() // -> call hàm của lớp BaseClass
        println("Hello from SubClass")
    }
}
  • Override với Interface
interface MyInterface {
    val name: String // interface của Kotlin có thể chứa member variable
    fun myFunction() {
    // interface của Kotlin có thể chứa hàm đã được định nghĩa sẵn
        println("Hello from MyInterface")
    }
    // interface của Kotlin có thể chứa hàm chưa được định nghĩa
    fun myEmptyFunction()
}

class MyClass : MyInterface {
// cách override trong Implementation của Interface
    override val name: String = "MyClass"
    override fun myFunction() {
        super.myFunction()
        println("Hello from MyClass")
    }

    override fun myEmptyFunction() {
        println("Hello from myEmptyFunction")
    }
}
  • Override với abstract class
abstract class MyAbstractClass {
    open val name: String = "Name"
    abstract val age: Int
    abstract fun myFunction()
    open fun myOpenFunction() {
        println("Hello from myEmptyFunction")
    }
    fun myNormalFunction() {
        println("Hello from myNormalFunction")
    }
}

class MySubClass : MyAbstractClass() {
    override val age: Int = 10
    override fun myFunction() {
        println("Hello from myFunction")
    }

    override fun myOpenFunction() {
        super.myOpenFunction()
    }

    override val name: String
        get() = super.name
}

Các câu hỏi khi áp dụng Polymorphism trong Kotlin

Câu hỏi 1: Điều khác biệt giữa kế thừa từ Class và Interface là gì?

Đáp: 1 Class chỉ có thể kế thừa từ 1 Class, nhưng có thể implement nhiều Interface.

Câu hỏi 2: Khi không muốn cho các module ngoài kế thừa Class, Interface bạn cần làm gì?

Đáp 2: Sử dụng sealed Class, Interface

Câu hỏi 3: Trong Kotlin abstract class và class khác biệt gì?

Đáp 3: class có thể được dùng để tạo object trực tiếp, abstract class thì không được.

Lưu ý: Interface, abstract Class vẫn có thể tạo được object thông qua object expression. Cách này không nên áp dụng cho các inteface, abstract class lớn. Vì sẽ làm code trở nên phức tạp, khó đọc, khó debug.

Chúc các bạn thành công!