2017-09-19 21 views
7

Tôi đang học Kotlin. Trước đó, tôi đã làm việc với Java để phát triển Android. Kotlin là một ngôn ngữ tuyệt vời để học. Tôi có một sự nhầm lẫn trong khi tôi đang sử dụng setOnClickListener(View.OnClickListener). Tôi đã thấy hai gợi ý trên Android Studio.Sự khác biệt giữa các phương pháp OnclickListener trong Kotlin

image

Tôi biết cách làm việc hoặc xác định cả hai.

Cách đầu tiên để thực hiện OnClickListerner

send_button.setOnClickListener(object : View.OnClickListener{ 
     override fun onClick(p0: View?) { 
      TODO("not implemented") //To change body of created functions use File | Settings | File Templates. 
     } 
    }) 

và đây là cách thứ hai thực hiện OnClickListener

send_button.setOnClickListener { 
     TODO("not implemented") //To change body of created functions use File | Settings | File Templates. 
    } 

Tôi hiểu như xa như phương pháp thứ hai được dựa trên lambda. Nhưng tôi không thể có sự hiểu biết đúng đắn về những phương pháp này.

Vì vậy, câu hỏi của tôi là: Sự khác nhau giữa các phương pháp đó là gì? Nếu chúng khác nhau, cái nào tốt hơn và tại sao?

Trả lời

2

Chúng tham chiếu đến cùng chức năng nhưng được viết theo cách khác. Cách đầu tiên là cách điển hình để gọi hàm setOnClickListener() chấp nhận đối tượng OnClickListener.

Cách thứ hai sử dụng biểu thức lambda. Nó hoạt động vì View.OnClickListener là một SAM type được xác định trong Java và Kotlin hỗ trợ SAM conversions.

Giống như Java 8, Kotlin hỗ trợ chuyển đổi SAM. Điều này có nghĩa là các hàm chức năng của Kotlin có thể được chuyển đổi tự động thành các giao diện Java với một phương thức không mặc định, miễn là các kiểu tham số của phương thức giao diện khớp với các kiểu tham số của hàm Kotlin.

Giả sử bạn có một giao diện được định nghĩa trong Java như thế này:

public class Example { 
    public interface SingleMethodInterface { 
     int length(String text); 
    } 

    public static void set(SingleMethodInterface sam) {} 
} 

Sau đó, bạn có thể gọi set() chức năng trong hai cách sau đây trong Kotlin:

//Passing a function type which accept a `String` and return an `Int` 
val length: (String) -> Int = { it.length } 
Example.set(length) 
//or 
Example.set { it.length } 

//Passing an object which implements `SingleMethodInterface` 
val length2: Main.SingleMethodInterface = object: Main.SingleMethodInterface { 
    override fun length(text: String): Int { 
     return text.length 
    } 
} 
Example.set(length2) 

Nói tóm lại, SAM chuyển đổi cung cấp một cách để viết mã sạch trong Kotlin mà interop với Java.

+0

Người đàn ông thông tin tốt, Nhưng ví dụ của bạn không liên quan đến câu hỏi của anh ấy. –

+0

@Bhuvanesh Bs Ví dụ tôi đã thêm được sử dụng để giải thích chuyển đổi SAM. – BakaWaii

+1

Cảm ơn bạn đã chia sẻ thông tin thú vị này @BakaWaii. – UltimateDevil

3

Câu hỏi của bạn: Sự khác nhau giữa các phương pháp đó là gì? Nếu chúng khác nhau, cái nào tốt hơn và tại sao?

Sau khi biên dịch, cả hai sẽ sản xuất cùng một bytecode nhưng trong khi viết nó sẽ cung cấp cho bạn dễ đọc hơn bằng cách thực hiện một dòng.

Tính năng tuyệt vời của Java 8 là biểu thức Lambda. Với Lambda bạn có thể viết mã java đơn giản hơn. Cái nhìn xấu xí của mã hơi bị thay đổi bởi tính năng này.

Ví dụ: source

Bạn có thể viết Độc Abstract Method (SAM) như lambda.

Nếu giao diện của bạn chỉ có một phương pháp.

public interface StateChangeListener { 

    public void onStateChange(State oldState, State newState); 

} 

Bạn có thể viết là Lambda như thế này.

stateOwner.addStateListener(
    (oldState, newState) -> System.out.println("State changed") 
); 

Nhưng cả hai phương pháp đều giống nhau nhưng bạn có thể thấy phương pháp thứ hai rất đơn giản và loại bỏ việc triển khai xấu xí.

Trong Kotlin, các biểu thức lambda khác với Java.

Kotlin lambda biểu ví dụ: source

val add: (Int, Int) -> Int = { a, b -> a + b } 

Biến chức năng trên có thể được gọi là như thế này:

val addedValue: Int = add(5, 5) 

này sẽ trả lại cho bạn những giá trị gia tăng của hai số nguyên.

Trong ví dụ này, bạn có thể xem (Int, Int) -> Int, hàm này được gọi là hàm lambda trong Kotlin.

Vì vậy, các hàm lambda của Kotlin lambda và Java lambda hoàn toàn khác nhau.

Bạn có thể nhìn thấy trong Kotlin Documents:

Cũng giống như Java 8, Kotlin hỗ trợ chuyển đổi SAM. Điều này có nghĩa là Các hàm chức năng Kotlin có thể được tự động chuyển đổi thành triển khai các giao diện Java với một phương thức không mặc định, miễn là các loại tham số của phương thức giao diện khớp với các loại tham số của hàm Kotlin.

Thực ra, bạn đang viết lambda trong kotlin, sau đó nó sẽ được chuyển thành giao diện java. Vì vậy, cả hai phương pháp đều khác nhau. Nhưng khi nói đến thực hiện cả hai đều giống nhau. Nó sẽ không ảnh hưởng đến thời gian biên dịch vì vậy nó luôn luôn được đề nghị sử dụng lambda.

Hy vọng điều này sẽ giúp ích:

+0

Ông yêu cầu sự khác biệt giữa phương pháp lambda và phương pháp thông thường. Vui lòng cập nhật câu trả lời của bạn @Intellij Amiya –

+1

Cảm ơn bạn đã trả lời @IntelliJAmiya. Nó giúp tôi hiểu rất nhiều. chuyển đổi setOnClickListener – UltimateDevil

Các vấn đề liên quan