Lập trình Kotlin — Lớp dữ liệu (data class)
Kotlin cung cấp cho chúng ta một lớp chuyên dụng cho việc lưu trữ dữ liệu với một số hàm được sinh ra sẵn phục vụ việc này.
Trong bài học trước chúng ta đã tìm hiểu về mở rộng trong Kotlin. Bài học hôm nay sẽ giới thiệu về lớp dữ liệu với mục đích chính là nắm giữ dữ liệu. Trong lập trình Kotlin, nó được gọi là lớp dữ liệu và được đánh dấu với từ khoá data
:
data class News(val title: String, val description: String)
Trình biên dịch tự động tạo ra những hàm dưới dựa vào các thuộc tính đã khai báo trong hàm khởi tạo đầu tiên.
- Cặp
equals() / hashCode()
- Hàm
toString()
// News(title=Good morning, description=This is a test) componentN()
, căn cứ vào số lượng và thứ tự của thuộc tính trong hàm khởi tạo đầu tiên.copy()
sẽ hiểu rõ ở phần sau.
fun main() {
val news = News("Good morning", "This is a test")
println(news.hashCode())
println(news.equals(45))
println(news.toString())
println(news.component1())
println(news.component2())
println(news.copy())
}
Để đảm bảo sự rõ nghĩa và thống nhất của các hàm được sinh ra ở trên, lớp dữ liệu phải đáp ứng một số yêu cầu sau:
- Hàm khởi tạo đầu tiên có ít nhất một thông số
- Các thông số trong hàm khởi tạo đầu tiên cần phải được khai báo với từ khoá
val
hoặcvar
- Lớp dữ liệu không thể là abstract, open, sealed hoặc inner
- Trước kotlin 1.1 các lớp dữ liệu có thể chỉ hiện thực các giao diện (
interfaces
)
Các hàm được sinh ra cũng tuân theo một số chuẩn của thành viên kế thừa như:
- Nếu một số hàm như
equals()
,hashCode()
hoặctoString()
đã được hiện thực trong lớp dữ liệu hoặc làfinal
trong lớp cha thì chúng không được sinh ra và dùng những hàm đã có sẵn - Nếu lớp dữ liệu cha có hàm
componentN()
và chúng là open và trả về kiểu dữ liệu tương ứng, những hàm này cũng sẽ được sinh ra tự động ở lớp con. Nếu những hàm đó được đánh dấu làfinal
ở lớp cha thì có lỗi xảy ra. - Kế thừa từ một lớp đã có sẵn hàm copy với thông số giống như hàm copy của lớp dữ liệu đã bắt đầu không hỗ trợ từ Kotlin 1.2 và không thể được từ Kotlin 1.3
Ví dụ ở lớp dữ liệu trên thì mặc đình là sẽ có hàm copy
như sau được sinh ra.
fun copy(title: String, description: String) {}
Nếu lớp News
kế thừa từ lớp có sẵn hàm này thì sẽ không được:
open class Test {
open var title: String = ""
open var description: String = ""
open fun copy(title: String, description: String) {}
}
data class News(override var title: String, override var description: String) : Test(){
}
- Trong lớp dữ liệu sẽ không cho hiện thực các hàm của
componentN()
vàcopy()
.
Từ Kotlin 1.1
lớp dữ liệu có thể kế thừa các lớp khác.
Trên máy ảo Java, nếu cần hàm khởi tạo với không tham số thì các giá trị mặc định cần được cung cấp cho lớp dữ liệu.
Thuộc tính khai báo bên trong thân của lớp dữ liệu
Thuộc tính bên trong lớp dữ liệu sẽ không được sinh ra cùng với những thành viên tự động sinh ra của lớp dữ liệu
data class Animal(val name: String) {
var legs: Int = 0
}
fun main() {
val cat = Animal("Cat")
cat.legs = 4
println(cat)
}
Hàm copy
Sẽ sao chép lại lớp dữ liệu với một số dữ liệu thay đổi.
fun copy(title: String = this.title, description: String = thisdescription) = News(title, description)
Các lớp dữ liệu và khai báo cấu trúc (destructuring declarations)
Các hàm component được sinh ra cho phép lớp dữ liệu được dùng trong khai báo cấu trúc.
val (title, description) = news
println("$title, $description of news")
Các lớp dữ liệu chuẩn
Thư viện chuẩn cung cấp Pair và Triple. Trong hầu hết các trường hợp, tên của lớp dữ liệu là lựa chọn tốt hơn trong thiết kế, bởi vì chúng làm code dễ đọc hơn và cung cấp tên dễ đọc hơn cho thuộc tính.
Cảm ơn các bạn đã đọc bài. Đăng ký kênh chúng tôi để xem những bài học mới nhất.
Youtube kênh: https://bit.ly/2EFOOXs
Thảo luận bằng cách comment ở đây hoặc trong video của blog này.