What's polymorphism

Tính đa hình (polymorphism) là một khái niệm trong lập trình hướng đối tượng, cho phép một đối tượng có thể thể hiện hành vi khác nhau dựa trên loại của nó. Cụ thể, trong Kotlin, tính đa hình thường được thể hiện thông qua việc sử dụng kế thừa và triển khai các phương thức abstract.

Khi một lớp con kế thừa từ một lớp cha và triển khai lại các phương thức abstract của lớp cha, ta có thể sử dụng đối tượng của lớp con đó như một đối tượng của lớp cha, và hành vi của phương thức abstract sẽ được xác định bởi triển khai trong lớp con đó.

Ưu điểm của tính đa hình

  1. Tính linh hoạt và tái sử dụng mã: Tính đa hình cho phép sử dụng các đối tượng của các lớp con trong ngữ cảnh của lớp cha mà không cần biết chi tiết về loại cụ thể của chúng. Điều này tạo ra sự linh hoạt trong việc tái sử dụng mã, vì chúng ta có thể thêm mới các lớp con mà không cần thay đổi mã của lớp cha.
  2. Tăng tính mở rộng: Tính đa hình cho phép mở rộng chức năng của ứng dụng mà không cần sửa đổi mã hiện có. Bằng cách thêm mới các lớp con hoặc triển khai lại các phương thức abstract trong các lớp con, chúng ta có thể mở rộng chức năng của hệ thống một cách dễ dàng mà không ảnh hưởng đến các phần khác của mã.
  3. Quản lý đa dạng: Tính đa hình cho phép quản lý các đối tượng đa dạng trong một cấu trúc chung. Điều này giúp giảm sự phức tạp của mã và làm cho mã dễ hiểu hơn.
  4. Tính đồng nhất (uniformity): Tính đa hình giúp tạo ra một giao diện đồng nhất cho các đối tượng khác nhau. Bằng cách sử dụng các phương thức và thuộc tính chung từ lớp cha, chúng ta có thể thao tác với các đối tượng khác nhau theo cách tương tự.
  5. Giảm thiểu sự phụ thuộc: Khi sử dụng tính đa hình, các đối tượng không cần biết chi tiết về loại cụ thể của các đối tượng mà chúng làm việc. Điều này giảm thiểu sự phụ thuộc giữa các phần của mã và làm cho mã dễ bảo trì hơn.

Ứng dụng trong Android

// Raw Model
abstract class BaseRaw<out BM : BaseModel> {
    abstract fun raw2Model(): BaseModel
}

class UserRaw(private val firstName: String, private val lastName: String) : BaseRaw<UserModel>() {
    override fun raw2Model(): UserModel {
        return UserModel(fullName = "$firstName $lastName")
    }
}

// Domain Model
abstract class BaseModel

class UserModel(val fullName: String) : BaseModel()

fun main() {
    val userRaw = UserRaw(firstName = "Doan", lastName = "Tuan")
    val userModel = userRaw.raw2Model()
    println("Full name = ${userModel.fullName}")
}
  1. Tham số kiểu có giới hạn (bounded type parameter):
  2. Override phương thức abstract: