2009-07-07 23 views
19

Czytam mojego Deitel, Java Jak zaprogramować książkę i natknąłem się na termin shadowing. Jeśli shadowing jest dozwolony, jaka jest sytuacja lub jaki jest jego cel w klasie Java?Na czym polega cieńowanie zmiennych w klasie Java?

Przykład:

public class Foo { 

    int x = 5; 

    public void useField() { 
     System.out.println(this.x); 
    } 
    public void useLocal() { 
     int x = 10; 
     System.out.println(x); 
    } 
} 

Odpowiedz

32

Podstawowym celem shadowingu jest oddzielenie kodu lokalnego od otaczającej go klasy. Jeśli nie było dostępne, rozważ następujący przypadek.

Zostaje wydana klasa Foo w interfejsie API. W swoim kodzie podklaskujecie go, aw swojej podklasie używaj zmiennej o nazwie bar. Następnie Foo wydaje aktualizację i dodaje do swojej klasy chronioną zmienną o nazwie Bar.

Teraz twoja klasa nie będzie biegać z powodu konfliktu, którego nie możesz przewidzieć.

Jednak nie rób tego celowo. Dopuść do tego tylko wtedy, gdy naprawdę nie dbasz o to, co dzieje się poza zakresem.

+7

Podoba mi się twój ostatni punkt: "Dopuść do tego tylko wtedy, gdy naprawdę nie dbasz o to, co dzieje się poza zakresem". ... będziesz wiedział, kiedy zacząć dbać, gdy coś dziwnego zacznie się dziać z wartością zmiennej instancji :))) W każdym razie, dobrą praktyką jest zawsze używać this.variable_name w swoich metodach ustawiających wartość instancji zmienna... – luigi7up

8

Jednym z głównych celem jest mylić ludzi. Jest to zła praktyka i należy jej unikać.

+0

Kontrowersyjna Zakładam ;-) –

+6

można dodatkowo wyjaśnić, jak this.x = x jest wcale skomplikowane? – RichieHH

13

To może być użyteczne dla ustawiaczy, gdzie nie chcą stworzyć osobną nazwę zmiennej dla parametru metoda np:

public void setX(int x) { 
    this.x = x; 
} 

Oprócz tego bym ich uniknąć.

+1

To jest straszny powód, by śledzić zmienne. Shadowing zawsze otwiera cię na potencjalne błędy i łatwiej jest nazwać zmienne informacjami o zasięgu, a także zmienić nazwę parametru, niż zawrzeć "to". każdego razu. – Rick

+3

Dla prostego setera, jak w powyższym przykładzie, myślę, że to dobrze, zmiana nazwy parametru sprawiłaby, że rzeczy były brzydkie. Coś bardziej skomplikowanego niż to, zgadzam się, całkowicie się unikaj. –

4

Shadowing nie jest tak naprawdę terminem java. W każdym przypadku, gdy zmienna zadeklarowana w zakresie ma tę samą nazwę, co w większym zakresie, ta zmienna jest zacieniona.

Niektóre typowe zastosowania cieniowania mają miejsce, gdy masz klasy wewnętrzne i zewnętrzne i chcesz zachować zmienną o tej samej nazwie.

Jeśli możesz tego uniknąć, powinieneś, ponieważ może to powodować zamieszanie.

1

Dwa typowe zastosowania są konstruktorzy i określone metody:

public Foo(int x) { 
    this.x = x; 
} 

public void setX(int x) { 
    this.x = x; 
} 

Bardzo occassionally to przydatne, jeśli chcesz kopię zmiennej w jednej chwili, lecz zmienna może zmienić w wywołaniu metody.

private void fire() { 
    Listener[] listeners = this.listeners; 
    int num = listeners.length; 
    for (int ct=0; ct<num; ++ct) { 
     listeners[ct].stateChanged(); 
    } 
} 

(oczywiście wymyślony przykład wykonany z eleganckiej zbędne do pętli.)

+0

Nie trzeba zacieniać dla żadnego z tych przypadków. – Rick

+1

@Rick Nikt nie mówił o tym, że jest to konieczne. Shadowing nie jest konieczne. –

+0

Mówię, że nigdy nie należy cienia. Po prostu nazwij zmienne inaczej. – Rick