Tìm hiểu về khái niệm Data Class trên Kotlin, so sánh với C# Struct
Kotlin Data Class

Tìm hiểu về khái niệm Data Class trên Kotlin, so sánh với C# Struct

Data Class trong Kotlin là các lớp được định nghĩa chỉ với mục đích lưu trữ dữ liệu/trang thái. Trong các ứng dụng phức tạp thường tồn tại một số lượng rất lớn các class được sử dụng như vậy. Data class được Kotlin bổ sung vào với mục đích giúp lập trình viên viết ích mã hơn, nó giúp mã nguồn của chúng ta thanh thoát và tinh tế hơn. Mặc dù có cách khai báo rất dễ lầm lẫn với khái niệm Struct trên C# nhưng Data Class là hoàn toàn khác với Struct nó không phải là sự bổ sung struct trên JVM – Java machine.

Khai báo Data Class

Cú pháp khai báo Data Class trong Kotlin

data class ClassNam (thuộc tính ...){}

Quy tắc khai báo Data Class

  • Phương thức khởi tạo phải có ít nhất 1 tham số.
  • Tham số của phương thức khởi tạo phải có khai báo var hay val
  • Data class không thể là abstractopensealed hoặc inner
  • Data class không nên kế thừa từ lớp khác (nhưng vẫn có thể implement interfaces)

Sau đây là một ví dụ về Data Class lưu trữ dữ liệu về một Person

data class Person(var name: String, var age:Int)

Lớp dự liệu Person này định nghĩa một đối tượng Person với 2 thuộc tính đi kèm là: name và age

Sự khác biệt chính giữa các lớp dữ liệu của Kotlin và các cấu trúc C # là các lớp dữ liệu của Kotlin vẫn là classes. Dữ liệu của Data Class được lưu trữ trên heap mà không phải trên stack. Các đối tượng này là đối tượng tham chiếu.

Thật vậy ta cùng xem ví dụ sau:

data class Person(var name: String, var age:Int)
fun main(args: Array<String>) {
    var p1:Person = Person("Cameo",32)
    var p2:Person = p1

    println(p1.toString())
    println(p2.toString())
    
    p1.name = "Cameo Plus"
    p1.age = 12
    
    println(p1.toString())
    println(p2.toString())
}

Kết quả của cụm code println là:

Person(name=Cameo, age=32)
Person(name=Cameo, age=32)
Person(name=Cameo Plus, age=12)
Person(name=Cameo Plus, age=12)

Mặc dù ta chỉ thay đổi giá trị thuộc tính của p1 nhưng p2 lại thay đổi theo ==> điều này xác minh cho vấn đề là dữ liệu được gọi theo kiểu tham chiếu đến vùng nhớ của JVM.

Tùy chỉnh giới hạn truy cập

Mặc định khi khai báo 1 Data Class bạn không cần phải tạo các phương thức truy cập get/set như java. Các phương thức truy cập trong Data Class sẽ được tạo mặc định khi ta định nghĩa 1 class. Xem lại ví dụ Data Class Person phía trên ta có thể dễ dàng truy cập các thuộc tính như sau:

data class Person(var name: String, var age:Int)
fun main(args: Array<String>) {
    var p1:Person = Person("Cameo",32)
    p1.name = "Cameo Plus"
    p1.age = 12
    println(p1.toString())
}

Để hạn chế truy cập các thuộc tính này chúng ta sử dụng từ khóa private

data class Person(private var name: String, var age:Int)
fun main(args: Array<String>) {
    var p1:Person = Person("Cameo",32)
    println(p1.toString())
    p1.name ="Cameo Plus"
    println(p1.toString())
}

Khi ta set dữ liệu cho thuộc tính name sẽ báo lỗi sau:

Error:(9, 7) Cannot access 'name': it is private in 'Person'

Và ta sử dụng câu lệnh sau vẫn báo lỗi như trên

fun main(args: Array<String>) {
    var p1:Person = Person("Cameo",32)
    println(p1.name)
}

Từ khóa private trong khai báo thuộc tính data class sẽ khóa truy cập get/set thuộc tính.

Tạo Data Class có thuộc tính Read Only – Chỉ đọc

Cùng xem 2 ví dụ dưới dây

data class Person(val name: String, val age:Int)
fun main(args: Array<String>) {
    var p1:Person = Person("Cameo",32)
    println("Person name is ${p1.name} and age is ${p1.age}")
}

===
Person name is Cameo and age is 32

data class Person(val name: String, val age:Int)
fun main(args: Array<String>) {
    var p1:Person = Person("Cameo",32)
    p1.name = "Cameo Plus"
    println("Person name is ${p1.name} and age is ${p1.age}")
}
===
Error:(8, 4) Val cannot be reassigned

Từ khóa val trong khai báo thuộc tính data class sẽ tạo thuộc tính chỉ đọc.

Phương thức sao chép copy()

Vì dữ liệu data class được đặt trên heap và là dữ liệu tham chiếu do đó nếu chúng ta muốn tạo 1 đối tượng mới từ đối tượng có sẵn chúng ta cần sử dụng phương thức copy() được cài đặt sẵn khi khai báo.

data class Person(var name: String, var age:Int)
fun main(args: Array<String>) {
    var p1:Person = Person("Cameo",32)
    var p2:Person = p1.copy()
    println("Person 1 name is ${p1.name} and age is ${p1.age}")
    p2.name = "Cameo Plus"
    p2.age = 16
    println("Person 2 name is ${p2.name} and age is ${p2.age}")
}

===
Person 1 name is Cameo and age is 32
Person 2 name is Cameo Plus and age is 16

Ngoài ra khi sử dụng copy() chúng ta có thể chỉ copy 1 vài thuộc tính từ đối tượng bị copy sang đối tượng cần copy

data class Person(var name: String, var age:Int)
fun main(args: Array<String>) {
    var p1:Person = Person("Cameo",32)
    var p2:Person = p1.copy("Cameo Plus")
    println("Person 1 name is ${p1.name} and age is ${p1.age}")
    println("Person 2 name is ${p2.name} and age is ${p2.age}")
}

===

Person 1 name is Cameo and age is 32
Person 2 name is Cameo Plus and age is 32

Trả lời

Website này sử dụng Akismet để hạn chế spam. Tìm hiểu bình luận của bạn được duyệt như thế nào.

Close Menu
×
×

Cart