Chào mừng các bạn đến với Cafedev! Hôm nay, chúng ta sẽ khám phá thế giới Kotlin với chủ đề “Functional SAM”. Tại Cafedev, chúng tôi đưa đến cho bạn những thông tin chi tiết và hữu ích về cách sử dụng giao diện hàm và chuyển đổi SAM để làm cho mã nguồn của bạn ngắn gọn và dễ đọc hơn. Hãy đồng hành cùng Cafedev để tận hưởng hành trình khám phá công nghệ và lập trình mới mẻ. Cùng bắt đầu hành trình với Kotlin và Functional \(SAM\) ngay hôm nay!.

Một giao diện chỉ có một phương thức trừu tượng được gọi là một giao diện hàm, hoặc một giao diện Đơn Trừu Tượng (SAM). Giao diện hàm có thể có nhiều thành viên không trừu tượng nhưng chỉ có một thành viên trừu tượng.
Để khai báo một giao diện hàm trong Kotlin, sử dụng từ khóa fun.

fun interface KRunnable {
   fun invoke()
}

1. Chuyển đổi SAM

Đối với các giao diện hàm, bạn có thể sử dụng chuyển đổi SAM giúp làm cho mã của bạn ngắn gọn và dễ đọc hơn bằng cách sử dụng biểu thức lambda.
Thay vì tạo một lớp triển khai một giao diện hàm thủ công, bạn có thể sử dụng một biểu thức lambda.Với chuyển đổi SAM, Kotlin có thể chuyển đổi bất kỳ biểu thức lambda nào có chữ ký phương thức duy nhất của giao diện thành mã, tạo động lập triển khai của giao diện.
Ví dụ, xem xét giao diện hàm Kotlin sau đây:

fun interface IntPredicate {
   fun accept(i: Int): Boolean
}

Nếu bạn không sử dụng chuyển đổi SAM, bạn sẽ cần viết mã như sau:

// Creating an instance of a class
val isEven = object : IntPredicate {
   override fun accept(i: Int): Boolean {
       return i % 2 == 0
   }
}

Bằng cách tận dụng chuyển đổi SAM của Kotlin, bạn có thể viết mã tương đương như sau thay vì:

// Creating an instance using lambda
val isEven = IntPredicate { it % 2 == 0 }

Một biểu thức lambda ngắn gọn thay thế toàn bộ mã không cần thiết.

fun interface IntPredicate {
   fun accept(i: Int): Boolean
}

val isEven = IntPredicate { it % 2 == 0 }

fun main() {
   println("Is 7 even? - ${isEven.accept(7)}")
}

Bạn cũng có thể sử dụng chuyển đổi SAM qua interface Java.

2. Di chuyển từ giao diện có hàm tạo đến giao diện hàm

Bắt đầu từ phiên bản 1.6.20, Kotlin hỗ trợ tham chiếu có thể gọi đến hàm tạo của giao diện hàm, thêm một cách tương thích nguồn để di chuyển từ một giao diện có hàm tạo đến một giao diện hàm.Xem xét mã sau:

interface Printer {
    fun print()
}

fun Printer(block: () -> Unit): Printer = object : Printer { override fun print() = block() }

Với tham chiếu có thể gọi đến hàm tạo của giao diện hàm được kích hoạt, mã này có thể được thay thế bằng chỉ một khai báo giao diện hàm:

fun interface Printer {
    fun print()
}

Hàm tạo của nó sẽ được tạo ra ngầm định, và bất kỳ mã nào sử dụng tham chiếu hàm ::Printer sẽ được biên dịch. Ví dụ:

documentsStorage.addPrinter(::Printer)

Bảo toàn tính tương thích nhị phân bằng cách đánh dấu hàm cũ Printer với @Deprecatedchú thích DeprecationLevel.HIDDEN:

@Deprecated(message = "Your message about the deprecation", level = DeprecationLevel.HIDDEN)
fun Printer(...) {...}

3. Giao diện hàm so với các bí danh kiểu

Bạn cũng có thể đơn giản chuyển viết lại đoạn mã trên sử dụng một bí danh kiểu cho một kiểu hàm:

typealias IntPredicate = (i: Int) -> Boolean

val isEven: IntPredicate = { it % 2 == 0 }

fun main() {
   println("Is 7 even? - ${isEven(7)}")
}

Tuy nhiên, các giao diện hàm và bí danh kiểu phục vụ mục đích khác nhau. Bí danh kiểu chỉ là tên cho các kiểu hiện có – chúng không tạo ra một kiểu mới, trong khi giao diện hàm lại làm điều đó. Bạn có thể cung cấp các tiện ích đặc biệt cho một giao diện hàm cụ thể để không áp dụng cho các hàm thường hoặc các bí danh kiểu của chúng.
Bí danh kiểu chỉ có thể có một thành viên, trong khi các giao diện hàm có thể có nhiều thành viên không trừu tượng và một thành viên trừu tượng. Giao diện hàm cũng có thể triển khai và mở rộng các giao diện khác.
Giao diện hàm linh hoạt hơn và cung cấp nhiều khả năng hơn so với bí danh kiểu, nhưng chúng có thể tốn kém hơn cả về mặt cú pháp và tại thời điểm chạy vì chúng có thể yêu cầu chuyển đổi thành một giao diện cụ thể. Khi bạn lựa chọn sử dụng cái nào trong mã của mình, hãy xem xét nhu cầu cụ thể của bạn:

  • Nếu API của bạn cần chấp nhận một hàm (bất kỳ hàm nào) với một số cụ thể về tham số và kiểu trả về – hãy sử dụng một kiểu hàm đơn giản hoặc định nghĩa một bí danh kiểu để đặt tên ngắn gọn cho kiểu hàm tương ứng.
  • * Nếu API của bạn chấp nhận một thực thể phức tạp hơn một hàm – ví dụ, nó có các hợp đồng phức tạp và/hoặc các thao tác không thể diễn đạt trong chữ ký của kiểu hàm – hãy khai báo một giao diện hàm riêng cho nó.

Cảm ơn bạn đã dành thời gian đọc về “Kotlin with Functional SAM” tại Cafedev! Chúng tôi hy vọng rằng bài viết đã mang lại những thông tin hữu ích và giúp bạn hiểu rõ hơn về cách tận dụng sức mạnh của giao diện hàm trong lập trình Kotlin. Đừng ngần ngại đặt câu hỏi và chia sẻ ý kiến của bạn tại Cafedev để chúng tôi có thể hỗ trợ bạn tốt hơn. Hãy tiếp tục đồng hành với chúng tôi trên Cafedev để khám phá thêm nhiều thông điệp và kiến thức mới từ cộng đồng lập trình. Cảm ơn bạn đã là một phần của Cafedev!

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!