Poznanie modyfikatora chronionego Javy

Mam klasę o nazwie A w pakiecie1 i inną klasę o nazwie C w pakiecie2. Klasa C rozszerza klasę A.

A ma zmienną instancji, która jest zadeklarowana w następujący sposób:

protected int protectedInt = 1;

Oto kod dla klasy A

package package1;

public class A {

    public int publicInt = 1;
    private int privateInt = 1;
    int defaultInt = 1;
    protected int protectedInt = 1;

}

A oto kod dla klasy C:

package package2;
import package1.A;

public class C extends A{

    public void go(){
        //remember the import statement
        A a = new A();
        System.out.println(a.publicInt);
        System.out.println(a.protectedInt);

    }
}

Eclipse podkreśla ostatni wiersz w C. go() i mówi, że "A. protectedInt" nie jest widoczny. Wydaje się, że jest to sprzeczne z definicją słowa kluczowego" chronionego", podaną w wyroczni dokumentacja.

Modyfikator protected określa, że członek może być dostępny tylko w jego własnym pakiecie (tak jak w pakiecie-private), a dodatkowo przez podklasę jego klasy w innym pakiecie.

Co tu się dzieje?
Author: mahela007, 2013-09-02

6 answers

Co tu się dzieje?

Źle zrozumiałeś Znaczenie protected. Możesz uzyskać dostęp do chronionych członków zadeklarowanych w A z C, ale tylko dla instancji C lub podklas C. Szczegóły dotyczące dostępu chronionego można znaleźć w sekcji 6.6.2 JLS . W szczególności:

Niech C będzie klasą, w której zadeklarowany jest chroniony element. Dostęp jest dozwolony tylko w ramach podklasy S C.

Dodatkowo, jeśli Id oznacza pole instancji lub metoda instancji, następnie:

  • [...]

  • Jeśli dostęp jest wyrażeniem dostępu do pola E.Id, gdzie E jest wyrażeniem podstawowym, lub metodą wywołania wyrażenia E.Id ( ... ) .), gdzie E jest wyrażeniem podstawowym, wtedy dostęp jest dozwolony wtedy i tylko wtedy, gdy typem E jest S lub podklasa s .

(podkreślenie moje.)

Więc ten kod będzie w porządku:

C c = new C();
System.out.println(c.publicInt);
System.out.println(c.protectedInt);
 39
Author: Jon Skeet,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-06-20 09:12:55

Ponieważ {[1] } jest dziedziczeniem A, C można bezpośrednio używać zmiennej protected z A Jak poniżej

public class C extends A{

    public void go(){

       System.out.println(protectedInt);

    }
}

Zgodnie z Twoim kodem tworzysz instancję A i uzyskujesz dostęp do zmiennej protected poprzez tę instancję , która narusza regułę Javy - chroniona zmienna nie jest widoczna poza pakietem

 11
Author: sanbhat,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-09-02 12:23:57
 public void go(){
        //remember the import statement
        A a = new A();
        System.out.println(a.publicInt);
        System.out.println(a.protectedInt);

    }

Kiedy robisz A a = new A(); i a.protectedInt próbujesz uzyskać dostęp do chronionego członka, który jest nielegalny zgodnie ze standardami java

Zamiast tego możesz zrobić this.protectedInt bezpośrednio.

 3
Author: Abhishek Singh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-09-02 12:20:28

Protected oznacza:

A) ten element będzie dostępny dla wszystkich klas w tym samym pakiecie poprzez odniesienie do obiektu.

B) dla różnych pakietów, będzie to dostępne tylko wewnątrz podklas a powiedzmy B, A użyte odniesienie może być instancją B lub dowolną podklasą B.

Weźmy przykład:

Niech Klasa rodzica be w jakimś pakiecie powie com.ex1 Niech B, C będą klasami w różnych pakietach w. r. t do A com.ex2. Również B extends A i C extends B. Będziemy zobacz jak możemy używać chronionego pola a wewnątrz B (podklasy A)

Kod A:

public class A {
    protected int a = 10;
}

Kod B:

public class B extends A {


    public void printUsingInheritance() {
        // Using this
        System.out.println(this.a);
    }


    public void printUsingInstantiation() {
        // Using instance of B
        B b = new B();
        System.out.println(b.a);

        // Using instance of C as C is subclass of B
        C c = new C();
        System.out.println(c.a);


        A a = new A();
        System.out.println(a.a); // Compilation error as A is not subclass of B
    }
}

Kod C:

public class C extends B {

}

For protected Static :

Obowiązują te same zasady, z wyjątkiem tego, że w b) teraz jest on dostępny w dowolnej podklasie A przez odniesienie do klasy A. odniesienie

 2
Author: Number945,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-06 20:57:07

Nie ma potrzeby tworzenia instancji klasy ochrony wewnątrz klasy Protection2. Można bezpośrednio wywołać chronioną zmienną bez tworzenia instancji klasy ochrony. Ponieważ Klasa Protection2 rozszerza klasę ochrony. Tak zmienna automatycznie dziedziczona przez podklasę.

Spróbuj użyć poniższego kodu:

public class Protection2 extends Protection{
Protection2()
{System.out.println("n_pro = " +n_pro);
}}
 1
Author: Sugumar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-12-17 05:45:56

W ramach tego samego pakietu, w którym deklarowany jest chroniony członek, dostęp jest dozwolony:

package package1;

public class C extends A{
    public void go(){
        A a = new A();
        System.out.println(a.protectedInt);  // got printed 
        C c = new C();
        System.out.println(c.protectedInt);  // got printed as well
    }
}

Poza pakietem, w którym zadeklarowany jest protected member, dostęp jest dozwolony wtedy i tylko wtedy, gdy za pomocą kodu odpowiedzialnego za implementację tego obiektu. W tym przypadku C jest odpowiedzialny za implementację tego obiektu, więc może uzyskać dostęp do protected.

package package2;

public class C extends A{
    public void go(){
        A a = new A();
        System.out.println(a.protectedInt);  // compiler complains  
        C c = new C();
        System.out.println(c.protectedInt);  // got printed
    }
} 
 1
Author: Ethan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-16 20:19:15