Domanda

Ho appena ricevuto un errore strano che coinvolge modificatore protetto.

Ho il codice seguente:

package p1;

public class C1 {
    protected void doIt() {}
}


package p2;

public class C2 extends p1.C1 {
    private C1 c1_instance;
    public void doItAgain() {
        c1_instance.doIt(); // wtf!!!!
    }
}

Ricevo errori, affermandolo doIt() ha accesso protetto e non può accedere! Ma sono in sottoclasse e ho e accesso a doIt() metodo.

Non è un bug?

È stato utile?

Soluzione

Ho anche avuto l'impressione di cosa protected significava "accessibile dallo stesso pacchetto o da una sottoclasse" ma il Specifica del linguaggio Java è ovviamente più preciso e spiega che in una sottoclasse S di C, "Se l'accesso è con un nome qualificato Q.id, dove Q è un nome di espressione, l'accesso è consentito se e solo se il tipo di espressione Q è S o una sottoclasse di S. "

Quindi puoi accedere solo a protected Metodo della superclasse tramite un riferimento alla sottoclasse da cui stai chiamando, in questo modo:

public class C2 extends C1 {
    private C2 c2_other_instance;
    public void doItAgain() {
        c2_other_instance.doIt();
    }
}

Se spieghi perché vuoi accedere a un'istanza della superclasse da un'istanza diversa della sottoclasse, qualcuno potrebbe essere in grado di suggerire un design migliore. Altrimenti dovrai creare il metodo public o mettere le classi nello stesso pacchetto.

Altri suggerimenti

In Java, non puoi chiamare protected metodi su un esempio diverso della classe base, anche dall'interno di una sottoclasse:

public class C2 extends p1.C1 {
    private C1 c1_instance;
    public void doItAgain() {
        doIt();             // fine
        c1_instance.doIt(); // disallowed
    }
}

L'unica eccezione è quando sia la classe base che la sottoclasse sono nello stesso pacchetto.

Per citare il Tutorial Java oo:

Il protected Il modificatore specifica che è possibile accedere al membro solo all'interno del proprio pacchetto (come con il pacchetto-privato) e, inoltre, da una sottoclasse della sua classe in un altro pacchetto.

Protetto è equivalente all'accesso a livello di pacchetto; Non puoi accedere al metodo se sei in un pacchetto diverso.

Dovresti essere in grado di chiamare Doit () direttamente senza passare attraverso l'oggetto C1_Instance, poiché C2 è una sottoclasse.

Da http://download.oracle.com/javase/tutorial/java/javaoo/accesscontrol.html

"Il modificatore protetto specifica che al membro è possibile accedere solo all'interno del proprio pacchetto (come con il pacchetto-privato) e, inoltre, da una sottoclasse della sua classe in un altro pacchetto."

C2 può essere una sottoblaction di C1, ma ciò non significa che possa accedere a tali metodi su un'istanza diversa, cioè C1_instance potrebbe non essere un'istanza di C2. Potresti accedervi se fosse nello stesso pacchetto.

No, protected Assicura l'accesso nello stesso pacchetto e nelle classi discendenti. Non sei né nello stesso pacchetto né lo stai accedendo direttamente da una classe discendente. C2 è un discendente ma c1_instance non è.

Se il tuo metodo è dichiarato protetto, puoi accedervi all'interno di questa classe, con il pacchetto e all'interno della sottoclasse.

Ora ecco la domanda, perché c'è un errore nonostante l'accesso a questo membro protetto dalla sua sottoclasse. La risposta è accedere al metodo protetto da una sottoclasse che la sottoclasse dovrebbe utilizzare il metodo direttamente dalla sottoclasse diretta. Qui la sottoclasse diretta è C2 ma l'istanza C1_Instance non lo è. È possibile utilizzare questo metodo direttamente (doit () al posto di c1_instance.doit ())

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top