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.
- Part 1: OOP Mastery: Các loại Class, Interface trong Kotlin
- Part 2: OOP Mastery: Encapsulation trong Kotlin
- Part 3: OOP Mastery: Inheritance trong Kotlin
- Part 4: OOP Mastery: Tính đa hình – Polymorphism trong Kotlin
- Part 5: OOP Mastery: Tính Trừu tượng – Abstraction trong Kotlin
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!