Chào mừng đến với Cafedev, nơi chúng tôi truyền đạt và chia sẻ kiến thức về lập trình! Hôm nay, chúng ta sẽ khám phá về “Class trong Kotlin”. Cùng Cafedev đắm chìm vào thế giới của lập trình hướng đối tượng với lớp(class) và đối tượng trong Kotlin. Việc sử dụng lớp(class) và đối tượng giúp chúng ta tổ chức và tối ưu hóa mã nguồn một cách hiệu quả. Hãy cùng nhau khám phá cách sử dụng lớp trong Kotlin để xây dựng ứng dụng mạnh mẽ và dễ bảo trì.”

Kotlin hỗ trợ lập trình hướng đối tượng với lớp và đối tượng. Đối tượng rất hữu ích để lưu trữ dữ liệu trong chương trình của bạn.
Lớp cho phép bạn khai báo một bộ đặc điểm cho một đối tượng. Khi bạn tạo đối tượng từ một lớp, bạn có thể tiết kiệm thời gian và công sức vì bạn không cần phải khai báo những đặc điểm này mỗi lần.

Để khai báo một lớp, sử dụng từ khóa class:

class Customer

1. Thuộc tính

Đặc điểm của một đối tượng lớp có thể được khai báo trong các thuộc tính. Bạn có thể khai báo thuộc tính cho một lớp:
* Trong dấu ngoặc đơn () sau tên lớp.

class Contact(val id: Int, var email: String)

* Trong phần thân lớp được định nghĩa bởi dấu ngoặc nhọn {}.

class Contact(val id: Int, var email: String) {
val category: String = ""
}

Chúng tôi khuyến nghị bạn khai báo thuộc tính là chỉ đọc (val) trừ khi chúng cần được thay đổi sau khi một thể hiện của lớp được tạo ra.

Bạn có thể khai báo thuộc tính mà không cần val hoặc var trong dấu ngoặc đơn nhưng những thuộc tính này không thể truy cập sau khi một thể hiện đã được tạo ra.

Nội dung nằm trong dấu ngoặc đơn () được gọi là phần đầu của lớp

Bạn có thể sử dụng một dấu phẩy cuối cùng khi khai báo thuộc tính lớp

Giống như với tham số hàm, thuộc tính lớp có thể có giá trị mặc định:

class Contact(val id: Int, var email: String = "example@gmail.com") {
val category: String = "work"
}

2. Tạo thể hiện

Để tạo một đối tượng từ một lớp, bạn khai báo một thể hiện của lớp sử dụng một constructor.

Theo mặc định, Kotlin tự động tạo một constructor với các tham số được khai báo trong phần đầu của lớp.

Ví dụ:

class Contact(val id: Int, var email: String)

fun main() {
val contact = Contact(1, "mary@gmail.com")
}

Trong ví dụ:
* Contact là một lớp.
* contact là một thể hiện của lớp Contact.
* idemail là các thuộc tính.
* idemail được sử dụng với constructor mặc định để tạo contact.

Các lớp Kotlin có thể có nhiều constructor, bao gồm cả những constructor bạn tự định nghĩa. Để biết thêm về cách khai báo
nhiều constructor, xem Constructors.

3. Truy cập thuộc tính

Để truy cập một thuộc tính của một thể hiện, viết tên thuộc tính sau tên thể hiện kèm theo dấu chấm .:

class Contact(val id: Int, var email: String)

fun main() {
val contact = Contact(1, "mary@gmail.com")

// Prints the value of the property: email
println(contact.email)

// mary@gmail.com
// Updates the value of the property: email
contact.email = "jane@gmail.com"

// Prints the new value of the property: email
println(contact.email)
// jane@gmail.com
}

Để nối giá trị của một thuộc tính vào một chuỗi, bạn có thể sử dụng các biểu diễn chuỗi ($).
Ví dụ:

println("Their email address is: ${contact.email}")

4. Hàm thành viên

Ngoài việc khai báo thuộc tính là một phần của đặc điểm của một đối tượng, bạn cũng có thể định nghĩa hành vi của đối tượng với các hàm thành viên.

Trong Kotlin, hàm thành viên phải được khai báo trong cơ thể lớp. Để gọi một hàm thành viên trên một thể hiện, viết tên hàm sau tên thể hiện kèm theo dấu chấm .. Ví dụ:

class Contact(val id: Int, var email: String) {
 fun printId() {
 println(id)
 }
}
fun main() {
val contact = Contact(1, "mary@gmail.com")
// Calls member function printId()
contact.printId()
// 1
}

5. Lớp dữ liệu

Kotlin có lớp dữ liệu (data classes) rất hữu ích để lưu trữ dữ liệu. Lớp dữ liệu có cùng chức năng với lớp, nhưng chúng tự động đi kèm với các hàm thành viên bổ sung. Những hàm thành viên này cho phép bạn dễ dàng in ra thông tin đọc được của thể hiện, so sánh các thể hiện của một lớp, sao chép các thể hiện và nhiều hơn nữa. Vì những hàm này
tự động có sẵn, bạn không cần phải dành thời gian viết code giống nhau cho mỗi lớp của bạn.

Để khai báo một lớp dữ liệu, sử dụng từ khóa data:

data class User(val name: String, val id: Int)

Những hàm thành viên được định nghĩa sẵn hữu ích nhất của lớp dữ liệu là:

Hàm Mô tả
.toString()In ấn một chuỗi có thể đọc được của thể hiện lớp và các thuộc tính của nó.
.equals() hoặc ==So sánh các thể hiện của một lớp.
.copy()Tạo một thể hiện của lớp bằng cách sao chép một thể hiện khác, có thể có một số thuộc tính khác nhau.

Xem các phần sau để xem ví dụ về cách sử dụng từng hàm:
* In dưới dạng chuỗi
* So sánh các thể hiện
* Sao chép thể hiện

5.1 In ấn dưới dạng chuỗi

Để in ra một chuỗi có thể đọc được của một thể hiện lớp, bạn có thể gọi rõ ràng hàm .toString(), hoặc sử dụng các hàm in (println()print()) mà tự động gọi .toString() cho bạn:

data class User(val name: String, val id: Int)

fun main() {
val user = User("Alex", 1)

//sampleStart
// Automatically uses toString() function so that output is easy to read
println(user)
// User(name=Alex, id=1)
//sampleEnd
}

Điều này đặc biệt hữu ích khi gỡ lỗi hoặc tạo logs.

5.2 So sánh các thể hiện

Để so sánh các thể hiện lớp dữ liệu, sử dụng toán tử bằng ==:

data class User(val name: String, val id: Int)

fun main() {
//sampleStart
val user = User("Alex", 1)
val secondUser = User("Alex", 1)
val thirdUser = User("Max", 2)

// Compares user to second user
println("user == secondUser: ${user == secondUser}")
// user == secondUser: true

// Compares user to third user
println("user == thirdUser: ${user == thirdUser}")
// user == thirdUser: false
//sampleEnd
}

5.3 Sao chép thể hiện

Để tạo một bản sao chính xác của một thể hiện lớp dữ liệu, gọi hàm .copy() trên thể hiện.

Để tạo một bản sao của một thể hiện lớp dữ liệu thay đổi một số thuộc tính, gọi hàm .copy() trên thể hiện thêm giá trị thay thế cho các thuộc tính như tham số hàm.

Ví dụ:

data class User(val name: String, val id: Int)

fun main() {
//sampleStart
val user = User("Alex", 1)
val secondUser = User("Alex", 1)
val thirdUser = User("Max", 2)

// Creates an exact copy of user
println(user.copy())
// User(name=Alex, id=1)

// Creates a copy of user with name: "Max"
println(user.copy("Max"))
// User(name=Max, id=1)

// Creates a copy of user with id: 3
println(user.copy(id = 3))
// User(name=Alex, id=3)
//sampleEnd
}

Việc tạo một bản sao của một thể hiện là an toàn hơn so với việc sửa đổi thể hiện gốc vì bất kỳ mã nào phụ thuộc vào thể hiện gốc đều không bị ảnh hưởng bởi bản sao và những gì bạn làm với nó.

Để biết thêm thông tin chi tiết hơn về lớp dữ liệu, xem Lớp dữ liệu.

6. Thực hành

6.2 Bài tập 1

Định nghĩa một lớp dữ liệu Employee với hai thuộc tính: một cho tên và một cho mức lương. Hãy đảm bảo rằng thuộc tính cho mức lương có thể thay đổi, nếu không bạn sẽ không nhận được tăng lương vào cuối năm! Hàm chính sẽ thể hiện cách bạn có thể sử dụng lớp dữ liệu này.

// Write your code here

Gợi ý:

fun main() {
val emp = Employee("Mary", 20)
println(emp)
emp.salary += 10
println(emp)
}

data class Employee(val name: String, var salary: Int)
fun main() {
val emp = Employee("Mary", 20)
println(emp)
emp.salary += 10
println(emp)
}

6.2 Bài tập 2

Để kiểm tra mã của bạn, bạn cần một bộ tạo ngẫu nhiên có thể tạo ra nhân viên ngẫu nhiên. Định nghĩa một lớp với một danh sách cố địnhtên tiềm năng (bên trong cơ thể lớp), và được cấu hình bởi một mức lương tối thiểu và tối đa (bên trong đầu lớp). Một lần nữa,
hàm chính sẽ thể hiện cách bạn có thể sử dụng lớp này.

List có một hàm mở rộng được gọi là .random()
trả về một phần tử ngẫu nhiên trong một danh sách.

Random.nextInt(from = ..., until = ...) trả về một số nguyên ngẫu nhiên trong giới hạn đã chỉ định.

import kotlin.random.Random

data class Employee(val name: String, var salary: Int)

// Write your code here
fun main() {
val empGen = RandomEmployeeGenerator(10, 30)
println(empGen.generateEmployee())
println(empGen.generateEmployee())
println(empGen.generateEmployee())
empGen.minSalary = 50
empGen.maxSalary = 100
println(empGen.generateEmployee())
}

Gợ ý:

import kotlin.random.Random

data class Employee(val name: String, var salary: Int)

class RandomEmployeeGenerator(var minSalary: Int, var maxSalary: Int) {
val names = listOf("John", "Mary", "Ann", "Paul", "Jack", "Elizabeth")
fun generateEmployee() =
Employee(names.random(),
Random.nextInt(from = minSalary, until = maxSalary))
}
fun main() {
val empGen = RandomEmployeeGenerator(10, 30)
println(empGen.generateEmployee())
println(empGen.generateEmployee())
println(empGen.generateEmployee())
empGen.minSalary = 50
empGen.maxSalary = 100
println(empGen.generateEmployee())
}

-> Kho tài liệu Free học Kotlin từ A->Z

Cuối cùng,

Cảm ơn bạn đã dành thời gian đọc về “Các lớp trong Kotlin” tại Cafedev. Chúng tôi hy vọng rằng thông tin chúng tôi chia sẻ đã giúp bạn hiểu rõ hơn về sức mạnh của lập trình hướng đối tượng trong Kotlin. Đừng ngần ngại trở lại để cập nhật kiến thức và đón đọc những bài viết mới tại Cafedev. Hãy tiếp tục hành trình lập trình của bạn cùng chúng tôi, Cafedev luôn ở đây để hỗ trợ và cùng chia sẻ niềm đam mê lập trình!”

Các nguồn kiến thức MIỄN PHÍ VÔ GIÁ từ cafedev tại đây

Nếu bạn thấy hay và hữu ích, bạn có thể tham gia các kênh sau của Cafedev để nhận được nhiều hơn nữa:

Chào thân ái và quyết thắng!

Đăng ký kênh youtube để ủng hộ Cafedev nha các bạn, Thanks you!