2015-11-22 13 views
5

Kotlin oferuje kilka z visibility modifiers, a także extension functions. Dokumentacja stwierdza, że ​​Extensions are resolved statically. Ale co to oznacza dla widoczności członków klasy w ramach funkcji rozszerzenia?Chronione elementy niedostępne w funkcjach rozszerzeń?

Rozważmy następujący przykład contrived:

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 

Kod nie skompiluje. Wygląda na to, że chronieni członkowie nie są dostępni podczas rozszerzania klasy.

Więc nie rozwiązany statycznie znaczy funkcja rozszerzenie jest cukier syntaktyczny za posiadanie czegoś takiego w Javie:

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

To wyjaśniałoby, dlaczego członkowie chronione nie są dostępne. Z drugiej strony można używać (i nawet pomijać) funkcje rozszerzenia.

Jaki jest dokładny zakres funkcji rozszerzenia?

Odpowiedz

6

Masz rację, funkcje rozszerzenia/właściwości są kompilowane do statycznych metod JVM. Zwykle znajdują się one w innej klasie w innym pakiecie niż klasa, którą rozszerzają, więc nie można wywoływać metod chronionych tej klasy z powodu zasad dostępności VM. Jest także zgodny z widocznością protected (widoczną w klasie i jej podklasach): funkcja rozszerzenia nie jest podklasą, ani nie jest zdefiniowana w podklasie rozszerzanej klasy.

Fakt, że można użyć lub pominąć this w ciele funkcji rozszerzenia, jest tylko funkcją syntaktyczną, kompilator emituje wymagane instrukcje, aby zamiast tego załadować pierwszy parametr metody JVM.