Perché una classe non può essere definita protetta?


So che questa è una domanda stupida, ma ho ancora un dubbio che deve essere chiarito.

La mia domanda è, perché non possiamo definire una classe come protected?

So che non possiamo, ma perché? Ci dovrebbe essere qualche motivo specifico.

Author: enveeed, 2010-10-06

12 answers

Perché non ha senso.

Protected class member (metodo o variabile) è proprio come package-private (visibilità predefinita), tranne per il fatto che è anche possibile accedervi dalle sottoclassi.
Poiché non esiste un concetto come "subpackage" o "package-inheritance" in Java, dichiarare class protected o package-private sarebbe la stessa cosa.

È possibile dichiarare le classi nidificate e interne come protette o private, tuttavia.

 68
Author: Nikita Rybak, 2010-10-06 04:49:13

Come sai il valore predefinito è per l'accesso a livello di pacchetto e protetto è per il livello di pacchetto più classi non-pacchetto ma che estende questa classe (il punto da notare qui è che puoi estendere la classe solo se è visibile!). Mettiamola in questo modo:

  • la classe di primo livello protetta sarebbe visibile alle classi nel suo pacchetto.
  • ora renderlo visibile al di fuori del pacchetto (sottoclassi) è un po ' confuso e complicato. Quali classi dovrebbero essere autorizzate a ereditare la nostra classe protetta?
  • Se tutte le classi sono autorizzate a sottoclasse, sarà simile allo specificatore di accesso pubblico.
  • Se nessuno allora è simile al default.

Poiché non c'è modo di limitare questa classe che viene sottoclassata solo da poche classi (non possiamo limitare la classe ereditata solo da poche classi di tutte le classi disponibili in un pacchetto/al di fuori di un pacchetto), non c'è uso di specificatori di accesso protetti per le classi di primo livello. Quindi non è permesso.

 29
Author: Akash5288, 2017-10-16 02:41:49
public class A
{
    protected class B
    {
    }
}
 13
Author: irreputable, 2010-10-06 04:51:13

La definizione di un campo protetto rende tale campo accessibile all'interno del pacchetto e all'esterno del pacchetto solo tramite ereditarietà (solo all'interno della classe figlio).

Quindi se ci è permesso di proteggere una classe, possiamo accedervi all'interno del pacchetto molto facilmente, ma per accedere a quella classe al di fuori del pacchetto dobbiamo prima estendere quell'entità in cui è definita questa classe che è il suo pacchetto.

E poiché un pacchetto non può essere esteso (può essere importato), definendo una classe protetta lo renderà nuovamente package-private che è simile a definirlo come predefinito che possiamo già fare. Pertanto non vi è alcun vantaggio nel definire una classe privata che renderà solo le cose ambigue.

Per ulteriori informazioni leggi Perché una classe Java esterna non può essere privata o protetta

 3
Author: Naresh Joshi, 2016-10-12 10:31:47

Dei 4 modificatori di accesso "pubblico, privato, protetto e predefinito" una classe può avere solo modificatore pubblico e predefinito.

Se hai una classe pubblica puoi usarla dove vuoi, il che è molto semplice. Puoi importarlo in qualsiasi pacchetto e iniziare a usarlo.

Ma, se hai una classe senza modificatore/predefinito, non puoi nemmeno importarla in un altro pacchetto. Ad esempio hai la classe:as DefaultClass.java

package home;
class DefaultClass{
..
}

E un'altra classe come Testarlo.java in un altro pacchetto.

package office;
import home.

Nel momento in cui si tenta di importare casa.DefaultClass nel codice precedente ti renderai conto che la nostra DefaultClass non può essere importata. Non è visibile a un pacchetto fuori casa. Non possiamo importarlo in questo TestingIt.file java. Perché no? perché default = limitato al proprio pacchetto.

E ora veniamo alla tua domanda " perché non è possibile che una classe abbia un modificatore di accesso protetto?" Penso che sia probabilmente perché non sarebbe diverso da un default / no classe modificatore. Anche se fosse possibile "classe protetta", non sarebbe possibile importarla in un altro pacchetto proprio come una"classe modificatore predefinita/no".

Potresti usarli nello stesso pacchetto, ma una volta importati entrambi funzionerebbero esattamente nello stesso pacchetto. Quindi, per quanto riguarda i modificatori di accesso per le classi, sia protetti che predefiniti sono gli stessi.

 2
Author: Er.Naved Ali, 2016-03-25 08:19:13

@Nikita Rybak answer ha buoni punti ma mancanza di dettagli, non posso semplicemente avere l'idea senza pensare profondamente me stesso, quanto segue è quello che ho pensato e ora dovrei capire completamente la ragione.

Quattro modificatori di accesso, supponiamo che il 1 ° livello sia pubblico e il 4 ° livello sia privato (basato su questa tabella in sequenza). La prima cosa che dovremmo sapere è perché la classe non può essere definita come privata nel livello superiore.

Quindi se"private class foo" (Un membro privato definito, cioè la classe stessa è un membro) consenti, qual è l'esterno (che contiene il membro) ? Ambito del file ? No, il file esterno è inutile perché anche più classi in un singolo file verranno compilate in file di classe separati. Quindi l'esterno è il pacchetto. Ma il modificatore di accesso predefinito di 3rd level significa già "package-private". Quindi il modificatore di accesso privato di 4 ° livello non verrà utilizzato / consentito.

Ma la classe privata annidata è consenti perché la diretta esterno è classe, non pacchetto, ad esempio :

class PrivateNestedMain {
    private static class Inner {
        public static void main(String[] args) {
            System.out.println("Hello from Inner!");
        }
    }
}

Ora cosa succede se" protected class foo " lo consente ? la caratteristica principale protetta è la sottoclasse, quindi l'esterno(pacchetto) DOVREBBE(a causa dell'ambito up-to, ma è comunque facoltativo) fornire stile di sottoclasse, cioè sub-pacchetto o package A extends package B, ma non sappiamo nulla. Quindi protected non può utilizzare il pieno potenziale(l'ambito principale è a livello di sottoclasse) nel livello superiore che l'esterno è pacchetto (cioè nessuna cosa del sub-pacchetto), ma protected può usare pieno potenziale nella classe nidificata che l'esterno è classe (cioè può essere sottoclasse):

class ProtectedNestedMain {
    protected static class Inner {
        public static void main(String[] args) {
            System.out.println("Hello from Inner!");
        }
    }
}

Si noti che quanto sopra detto "non può utilizzare il pieno potenziale" a causa del fatto che non può raggiungere la sottoclasse solo perché nessuna sottoclasse esterna, questo significa che effettivamente protetto può essere consentito, è solo una questione di scelta evitare di duplicare il lavoro di package-private se esterno non sottoclassabile, vedi sotto.

La mia confusione è causata principalmente dal famoso tavolo a https://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html :

inserisci qui la descrizione dell'immagine

Se il 1 ° livello(pubblico) e il 3 ° livello (pacchetto-privato) sono consentiti, come mai il 2 ° livello intermedio (protetto) non è consentito ?

Supporto pubblico sottoclasse così facile da fuorviante. Il modo corretto di leggere questa tabella è

Sottoclasse di supporto pubblico se l'esterno ha funzionalità di sottoclasse.

Lo stesso fuorviante si applica a pacakage-private, pacakage-private non supporta la sottoclasse (N nella cella) non significa che il concetto di sottoclasse si applichi in outer.

Significa che dovremmo ignorare la colonna Sottoclasse se la funzionalità sottoclasse non è disponibile in outer:

inserisci qui la descrizione dell'immagine

Come possiamo vedere ora, sia protected che package-private hanno lo stesso livello ora ( Y-Y-N), non c'è più confusione sul motivo per cui il livello intermedio non è consentito. Nel complesso, Java sceglie solo pacchetto-privato su protetto per evitare confusioning ( è solo una questione di scelta, ma la caratteristica principale protetta è sottoclasse, quindi package-private è superiore) e il risultato , solo 2 modificatori di accesso consentiti nel livello superiore:

Al livello superiore-pubblico, o pacchetto-privato (nessun modificatore esplicito).

 1
Author: 林果皞, 2017-05-23 12:26:07

Protetto non è simile a pubblico. Protetto ha sia l'accesso a livello di pacchetto più è possibile accedere al di fuori dei pacchetti solo per ereditarietà..Se una classe dice A al di fuori di un pacchetto EREDITA una classe da un altro pacchetto(con metodo protetto usando l'EREDITARIETÀ) può accedere ai metodi di questa classe B che ha metodi protetti ma le sottoclassi derivate da questa classe, ad esempio, A non può accedere ai metodi protetti..il contrario accade con il pubblico..

Esempio:

package 2;
class B
{
protected void method1()
{
}
}
package 1;
import 2.B;
class A extends B
{
//can access protected method
}
class C extends A
{
//can't access the protected method
}
 1
Author: Shruthi reddy, 2017-03-07 04:12:22

Comportamento di "protected" = comportamento di "default"+ "usalo in qualsiasi sottoclasse in qualsiasi pacchetto".

In ogni caso abbiamo modificatore di accesso predefinito per la classe, l'unico vantaggio che possiamo ottenere dal modificatore di accesso protetto è:- usandolo in qualsiasi pacchetto attraverso sottoclassi. Ma per la sottoclasse, la visibilità della classe "protetta" genitore sarebbe privata. Quindi non è possibile accedervi. Fondamentalmente se si dispone di una classe di primo livello protetta, nessuna classe esterna può accedere sottoclassandola. Così protetto per un top-level la classe non ha senso.

 0
Author: madhu, 2014-07-03 15:43:14

Protetto: VISIBILE solo a livello di pacchetto*.

La classe è definita protetta ---> non può essere esteso dal pacchetto esterno(non visibile).

E se non può essere esteso, non ha senso mantenerlo come protetto, perché allora diventerà l'accesso predefinito che è consentito.

Lo stesso vale per le classi definite private.

Nota: è possibile definire classi nidificate o interne protetto o privato .

* : Esplora la parola chiave protetta , per questa risposta l'ho resa succinta.

 0
Author: Narendra Singh, 2018-03-14 10:03:22

La risposta di @ Akash5288 non aveva senso per me:

Se tutte le classi sono autorizzate a sottoclasse, sarà simile allo specificatore di accesso pubblico.

Poiché non c'è modo di limitare questa classe che viene sottoclassata solo da poche classi (non possiamo limitare la classe ereditata solo da poche classi di tutte le classi disponibili in un pacchetto/al di fuori di un pacchetto), non c'è uso di specificatori di accesso protetti per le classi di primo livello. Quindi non lo è permettere.

È quindi possibile applicare la stessa logica ai metodi e alle variabili protette, che sono anche "simili a public". Tutte le classi al di fuori di un pacchetto possono estendere la nostra classe pubblica e utilizzare i suoi metodi protetti. Perché limitare i metodi e le variabili alle classi estese va bene, ma limitare l'intera classe non va bene? "Simile al pubblico" non è "uguale al pubblico". La mia interpretazione è che va perfettamente bene consentire una classe protetta, come va bene consentire protetta metodo.

La risposta "non puoi estendere una classe a cui non puoi accedere/vedere" è più logica.

 0
Author: k-s, 2018-04-12 03:06:44

Ciò che ha senso a questa domanda è che, JVM è scritto in C (Sun JVM) e C++(oracle JVM) quindi durante la compilazione, creeremo .file di classe dal nostro file java e se dichiariamo una classe con parola chiave protetta, non sarà accessibile da JVM.

La risposta per cui la classe protetta non sarà accessibile da JVM è che, poiché i campi protetti sono accessibili all'interno dello stesso pacchetto o al pacchetto diverso solo attraverso l'ereditarietà e JVM non è scritto in modo tale che erediterà la classe will. Spero che questo soddisfi questa domanda:)

Allo stesso modo, una classe di livello superiore non può essere privata. Spiegazione come qui sotto:

Quindi cosa succederà se definiremo una classe privata, quella classe sarà accessibile solo all'interno dell'entità in cui è definita che nel nostro caso è il suo pacchetto?

Quindi definire l'accesso privato alla classe lo renderà accessibile all'interno dello stesso pacchetto che la parola chiave predefinita già fa per noi, quindi non vi è alcun vantaggio di definire una classe privata renderà solo le cose ambigue.

 0
Author: Anurag Prasad, 2018-07-04 14:20:48
protected means that the member can be accessed by any class in the same package 
and by sub classes even if they are in another packages.
example:
    package a;
    class parent{
     protected void p();
    }
    package b;
    import a.p;
    class child extends parent{
      //you can access method which is protected in the parent in the child 
    }
    class another extends child {
     //here you can not access the protected method 
    }
 0
Author: Yogesh Patil, 2018-09-01 19:22:12