Trong bài viết này, bạn sẽ tìm hiểu về nạp chồng toán tử (xác định cách toán tử hoạt động cho các kiểu do người dùng xác định như đối tượng) với sự trợ giúp của các ví dụ.

Khi bạn sử dụng toán tử trong Kotlin, hàm thành viên tương ứng của nó sẽ được gọi. Ví dụ: biểu thức a+b biến đổi thành a.plus(b).

fun main(args: Array<String>) {
    val a = 5
    val b = 10

    print(a.plus(b)) // print(a+b)
}

Khi bạn chạy chương trình, kết quả sẽ là:

15

Trên thực tế, hàm plus() được nạp chồng để hoạt động với các kiểu dữ liệu cơ bản khác nhau trong Kotlin và String.

// + operator for basic types
operator fun plus(other: Byte): Int
operator fun plus(other: Short): Int
operator fun plus(other: Int): Int
operator fun plus(other: Long): Long
operator fun plus(other: Float): Float
operator fun plus(other: Double): Double

// for string concatenation
operator fun String?.plus(other: Any?): String

Bạn cũng có thể xác định cách toán tử hoạt động cho các đối tượng bằng cách nạp chồng hàm tương ứng của nó. Ví dụ, bạn cần xác định cách toán tử + hoạt động cho các đối tượng bằng cách nạp chồng hàm plus().

Ví dụ: Nạp chồng toán tử + 

fun main(args: Array<String>) {
    val p1 = Point(3, -8)
    val p2 = Point(2, 9)

    var sum = Point()
    sum = p1 + p2

    println("sum = (${sum.x}, ${sum.y})")
}

class Point(val x: Int = 0, val y: Int = 10) {

    // overloading plus function
    operator fun plus(p: Point) : Point {
        return Point(x + p.x, y + p.y)
    }
}

Khi bạn chạy chương trình, kết quả sẽ là:

sum = (5, 1)

Ở đây, hàm plus() được đánh dấu bằng từ khóa operator để cho trình biên dịch biết rằng toán tử + đang được nạp chồng.

Biểu thức p1 + p2 được chuyển thành p1.plus(p2).

Ví dụ: nạp chồng toán tử – 

Trong ví dụ này, bạn sẽ học cách nạp chồng toán tử –. Biểu thức –a được chuyển thành a.dec().

Hàm thành viên dec() không nhận bất kỳ đối số nào.

fun main(args: Array<String>) {
    var point = Point(3, -8)
    --point

    println("point = (${point.x}, ${point.y})")
}

class Point(var x: Int = 0, var y: Int = 10) {
    operator fun dec() = Point(--x, --y)
}

Khi bạn chạy chương trình, phần mở rộng sẽ là:

point = (2, -9)

Hãy ghi nhớ rằng:

operator fun dec() = Point(--x, --y)

tương đương với

operator fun dec(): Point {
    return Point(--x, --y)
}

Một vài điểm quan trọng

1. Khi bạn nạp chồng các, bạn nên cố gắng duy trì ý nghĩa ban đầu của toán tử. Ví dụ,

/*
Cafedev.vn - Kênh thông tin IT hàng đầu Việt Nam
@author cafedevn
Contact: cafedevn@gmail.com
Fanpage: https://www.facebook.com/cafedevn
Group: https://www.facebook.com/groups/cafedev.vn/
Instagram: https://instagram.com/cafedevn
Twitter: https://twitter.com/CafedeVn
Linkedin: https://www.linkedin.com/in/cafe-dev-407054199/
Pinterest: https://www.pinterest.com/cafedevvn/
YouTube: https://www.youtube.com/channel/UCE7zpY_SlHGEgo67pHxqIoA/
*/

fun main(args: Array<String>) {
    val p1 = Point(3, -8)
    val p2 = Point(2, 9)

    var sum = Point()
    sum = p1 + p2

    println("sum = (${sum.x}, ${sum.y})")
}

class Point(val x: Int = 0, val y: Int = 10) {

    // overloading plus function
    operator fun plus(p: Point) = Point(x - p.x, y - p.y)
}

Mặc dù chương trình trên đúng về mặt kỹ thuật nhưng chúng ta đã sử dụng toán tử + để trừ các thuộc tính tương ứng của hai đối tượng khiến chương trình trở nên rất khó hiểu.

2. Không giống như các ngôn ngữ lập trình như Scala, chỉ có một tập hợp toán tử cụ thể mới có thể được nạp chồng trong Kotlin . Truy cập trang để tìm hiểu về các toán tử có thể được nạp chồng trong Kotlin và các hàm thành viên tương ứng của chúng.

Tài liệu từ cafedev:

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!