2015-11-22 17 views
5

Kotlin có một số visibility modifiers cũng như extension functions. Tài liệu nêu rõ rằng Extensions are resolved statically. Nhưng điều này có ý nghĩa gì đối với khả năng hiển thị của các thành viên lớp trong các hàm mở rộng?Thành viên được bảo vệ không thể truy cập trong các chức năng mở rộng?

Hãy xem xét các ví dụ contrived sau:

class A { protected val a = "Foo" } 
fun A.ext() { print(a) } //Raises: Cannot access 'a': it is 'protected' in 'A' 

class B { val b = "Bar" } 
fun B.ext() { print(b) } //Compiles successful 

Mã sẽ không biên dịch. Dường như các thành viên được bảo vệ không thể truy cập được khi mở rộng lớp.

Vì vậy, hiện giải quyết tĩnh có nghĩa là chức năng mở rộng là đường cú pháp để có một cái gì đó như thế này trong Java:

public static void ext(A receiver){ System.out.print(receiver.a); } 

này sẽ giải thích lý do tại sao các thành viên bảo vệ không thể truy cập. Mặt khác, có thể sử dụng (và thậm chí bỏ qua) this trong các chức năng mở rộng.

Vì vậy, phạm vi chính xác của các chức năng mở rộng là gì?

Trả lời

6

Bạn đúng, các hàm/thuộc tính mở rộng được biên dịch thành các phương pháp JVM tĩnh. Nói chung, chúng được đặt trong một lớp khác trong một số gói khác so với lớp mà chúng đang mở rộng, do đó không thể gọi các phương thức được bảo vệ của lớp đó do các quy tắc về khả năng truy cập VM. Nó cũng phù hợp với khả năng hiển thị protecteddefinition (hiển thị trong lớp và các lớp con của nó): một hàm mở rộng không phải là lớp con, cũng không được định nghĩa trong lớp con của lớp bạn đang mở rộng.

Thực tế là bạn có thể sử dụng hoặc bỏ qua this trong phần thân của hàm mở rộng chỉ là một tính năng cú pháp, trình biên dịch phát ra các hướng dẫn bắt buộc để tải tham số đầu tiên của phương pháp JVM.

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