private package - Qual è la differenza tra pubblico, protetto, pacchetto-privato e privato in Java?



import come (21)

In Java, ci sono regole chiare su quando utilizzare ognuno dei modificatori di accesso, vale a dire il predefinito (pacchetto privato), public , protected e private , mentre si fa class e interface e si occupa dell'ereditarietà?


Answers

Visibile al pacchetto. Il predefinito. Non sono necessari modificatori.

Visibile solo alla classe ( privata ).

Visibile al mondo ( pubblico ).

Visibile al pacchetto e a tutte le sottoclassi ( protette ).

Variabili e metodi possono essere dichiarati senza alcun modificatore chiamato. Esempi predefiniti:

String name = "john";

public int age(){
    return age;
}

Modificatore di accesso privato - privato:

Metodi, variabili e costruttori dichiarati privati ​​sono accessibili solo all'interno della classe dichiarata. Il modificatore di accesso privato è il livello di accesso più restrittivo. La classe e le interfacce non possono essere private.

Le variabili dichiarate private sono accessibili al di fuori della classe se nella classe sono presenti metodi getter pubblici.

L'utilizzo del modificatore privato è il modo principale in cui un oggetto si incapsula e nasconde i dati dal mondo esterno.

Esempi:

Public class Details{

    private String name;

    public void setName(String n){
        this.name = n;
    }

    public String getName(){
        return this.name;
    }
}

Modificatore di accesso pubblico - pubblico:

Una classe, metodo, costruttore, interfaccia, ecc. Dichiarato pubblico può essere accessibile da qualsiasi altra classe. Pertanto è possibile accedere a campi, metodi, blocchi dichiarati all'interno di una classe pubblica da qualsiasi classe appartenente all'universo Java.

Tuttavia, se la classe pubblica a cui stiamo tentando di accedere si trova in un pacchetto diverso, la classe pubblica deve ancora essere importata.

A causa dell'ereditarietà delle classi, tutti i metodi pubblici e le variabili di una classe sono ereditati dalle sue sottoclassi.

Esempio:

public void cal(){

}

Modificatore di accesso protetto - protetto:

Variabili, metodi e costruttori che sono dichiarati protetti in una superclasse sono accessibili solo dalle sottoclassi di un altro pacchetto o di qualsiasi classe all'interno del pacchetto della classe dei membri protetti.

Il modificatore di accesso protetto non può essere applicato alla classe e alle interfacce. Metodi, i campi possono essere dichiarati protetti, tuttavia i metodi e i campi in un'interfaccia non possono essere dichiarati protetti.

L'accesso protetto consente alla sottoclasse di utilizzare il metodo o la variabile helper, impedendo al contempo a una classe non correlata di tentare di utilizzarla.

class Van{

    protected boolean speed(){

    }
}

class Car{
    boolean speed(){
    }

}

Quando stai pensando ai modificatori di accesso, pensaci in questo modo (si applica a variabili e metodi ):

public-> accessibile da ogni dove
private-> accessibile solo all'interno della stessa classe in cui è dichiarato

Ora la confusione sorge quando si tratta di defaulteprotected

default-> Non è presente alcuna parola chiave modificatore di accesso. Ciò significa che è disponibile rigorosamente all'interno del pacchetto della classe. In nessun posto al di fuori di questo pacchetto è possibile accedere.

protected-> Leggermente meno severo rispetto defaulte a parte le stesse classi di pacchetti a cui è possibile accedere da sottoclassi al di fuori del pacchetto dichiarato.


Modificatori di accesso in Java.

I modificatori di accesso Java vengono utilizzati per fornire il controllo degli accessi in Java.

1. Predefinito:

Accessibile solo alle classi nello stesso pacchetto.

Per esempio,

// Saved in file A.java
package pack;

class A{
  void msg(){System.out.println("Hello");}
}

// Saved in file B.java
package mypack;
import pack.*;

class B{
  public static void main(String args[]){
   A obj = new A(); // Compile Time Error
   obj.msg(); // Compile Time Error
  }
}

Questo accesso è più limitato di pubblico e protetto, ma meno limitato del privato.

2. Pubblico

Si può accedere da qualsiasi luogo. (Accesso globale)

Per esempio,

// Saved in file A.java

package pack;
public class A{
  public void msg(){System.out.println("Hello");}
}

// Saved in file B.java

package mypack;
import pack.*;

class B{
  public static void main(String args[]){
    A obj = new A();
    obj.msg();
  }
}

Uscita: Ciao

3. Privato

Accessibile solo all'interno della stessa classe.

Se si tenta di accedere a membri privati ​​su una classe in un'altra verrà generato un errore di compilazione. Per esempio,

class A{
  private int data = 40;
  private void msg(){System.out.println("Hello java");}
}

public class Simple{
  public static void main(String args[]){
    A obj = new A();
    System.out.println(obj.data); // Compile Time Error
    obj.msg(); // Compile Time Error
  }
}

4. Protetto

Accessibile solo alle classi nello stesso pacchetto e alle sottoclassi

Per esempio,

// Saved in file A.java
package pack;
public class A{
  protected void msg(){System.out.println("Hello");}
}

// Saved in file B.java
package mypack;
import pack.*;

class B extends A{
  public static void main(String args[]){
    B obj = new B();
    obj.msg();
  }
}

Uscita: Ciao


Questa pagina descrive bene il modificatore di accesso protetto e predefinito

.... Protetto: il modificatore di accesso protetto è un po 'complicato e si può dire che è un superset del modificatore di accesso predefinito. I membri protetti sono uguali ai membri predefiniti per quanto riguarda l'accesso nello stesso pacchetto. La differenza è che i membri protetti sono anche accessibili alle sottoclassi della classe in cui è dichiarato il membro che si trovano all'esterno del pacchetto in cui è presente la classe genitore.

Ma questi membri protetti sono "accessibili al di fuori del pacchetto solo attraverso l'ereditarietà". vale a dire che puoi accedere ad un membro protetto di una classe nella sua sottoclasse presente in qualche altro pacchetto direttamente come se il membro fosse presente nella sottoclasse stessa. Ma quel membro protetto non sarà accessibile nella sottoclasse esterna al pacchetto usando il riferimento della classe genitore. ....


I modificatori di accesso sono lì per limitare l'accesso a diversi livelli.

Pubblico: è fondamentalmente tanto semplice quanto è possibile accedere da qualsiasi classe, indipendentemente dal fatto che si trovi nello stesso pacchetto o meno.

Per accedere se si è nello stesso pacchetto è possibile accedere direttamente, ma se si è in un altro pacchetto, è possibile creare un oggetto della classe.

Predefinito: è accessibile nello stesso pacchetto da qualsiasi classe di pacchetto.

Per accedere puoi creare un oggetto della classe. Ma non puoi accedere a questa variabile al di fuori del pacchetto.

Protetto: puoi accedere alle variabili nello stesso pacchetto e sottoclasse in qualsiasi altro pacchetto. quindi in pratica è predefinito + comportamento ereditato .

Per accedere al campo protetto definito nella classe base è possibile creare l'oggetto della classe figlio.

Privato: può essere accesso nella stessa classe.

Nei metodi non statici è possibile accedere direttamente a causa di questo riferimento (anche nei costruttori) ma per accedere ai metodi statici è necessario creare l'oggetto della classe.


                | highest precedence <---------> lowest precedence
*———————————————+———————————————+———————————+———————————————+———————
 \ xCanBeSeenBy | this          | any class | this subclass | any
  \__________   | class         | in same   | in another    | class
             \  | nonsubbed     | package   | package       |    
Modifier of x \ |               |           |               |       
————————————————*———————————————+———————————+———————————————+———————
public          |       ✔       |     ✔     |       ✔       |   ✔   
————————————————+———————————————+———————————+———————————————+———————
protected       |       ✔       |     ✔     |       ✔       |   ✘   
————————————————+———————————————+———————————+———————————————+———————
package-private |               |           |               |
(no modifier)   |       ✔       |     ✔     |       ✘       |   ✘   
————————————————+———————————————+———————————+———————————————+———————
private         |       ✔       |     ✘     |       ✘       |   ✘    

Privato : accesso limitato alla sola classe

Predefinito (nessun modificatore) : accesso limitato alla classe e al pacchetto

Protetto : accesso limitato a classi, pacchetti e sottoclassi (pacchetto interno ed esterno)

Pubblico : accessibile per classe, pacchetto (tutti) e sottoclassi ... In breve, ovunque.


Spesso mi sono reso conto che ricordare i concetti base di qualsiasi linguaggio può essere reso possibile creando analogie del mondo reale. Ecco la mia analogia per la comprensione dei modificatori di accesso in Java:

Supponiamo che tu sia uno studente in un'università e che tu abbia un amico che viene a trovarti durante il fine settimana. Supponiamo che esista una grande statua del fondatore dell'università nel mezzo del campus.

  • Quando lo porti al campus, la prima cosa che tu e il tuo amico vedete è questa statua. Ciò significa che chiunque cammini nel campus può guardare la statua senza il permesso dell'università. Questo rende la statua PUBBLICA .

  • Quindi, vuoi portare il tuo amico nel tuo dormitorio, ma per farlo devi registrarlo come visitatore. Ciò significa che ottiene un pass di accesso (che è uguale al tuo) per accedere a vari edifici nel campus. Questo renderebbe la sua carta di accesso PROTETTA .

  • Il tuo amico vuole accedere al WiFi del campus ma non ha le credenziali per farlo. L'unico modo in cui può essere online è se condividi il tuo login con lui. (Ricorda, tutti gli studenti che frequentano l'università possiedono anche queste credenziali di accesso). Ciò renderebbe le credenziali di accesso come NO MODIFIER .

  • Infine, il tuo amico vuole leggere il tuo rapporto sui progressi per il semestre che viene pubblicato sul sito web. Tuttavia, ogni studente ha il proprio login personale per accedere a questa sezione del sito web del campus. Ciò renderebbe queste credenziali PRIVATE .

Spero che questo ti aiuti!


Si tratta di incapsulamento (o come affermava Joe Phillips, minima conoscenza ).

Inizia con il più restrittivo (privato) e vedi se hai bisogno di modificatori meno restrittivi in ​​seguito.

Usiamo tutti i metodi e i modificatori dei membri come privati, pubblici, ... ma una cosa che pochi sviluppatori fanno è usare i pacchetti per organizzare il codice logicamente.

Ad esempio: puoi mettere i metodi di sicurezza sensibili in un pacchetto di 'sicurezza'. Quindi inserisci una classe pubblica che acceda ad alcuni dei codici relativi alla sicurezza in questo pacchetto, ma mantieni privato il pacchetto di altre classi di sicurezza . Pertanto, altri sviluppatori potranno utilizzare la classe pubblicamente disponibile al di fuori di questo pacchetto (a meno che non modifichino il modificatore). Questa non è una funzione di sicurezza, ma guiderà l' utilizzo.

Outside world -> Package (SecurityEntryClass ---> Package private classes)

Un'altra cosa è che le classi che dipendono molto l'una dall'altra possono finire nello stesso pacchetto e potrebbero eventualmente essere refactored o unite se la dipendenza è troppo forte.

Se invece si imposta tutto come pubblico non sarà chiaro a cosa si deve o non si deve accedere, il che può portare a scrivere un sacco di javadoc (che non impone nulla tramite il compilatore ...).


(Caveat: Io non sono un programmatore Java, sono un programmatore Perl. Perl non ha protezioni formali che è forse il motivo per cui capisco il problema così bene :))

Privato

Come penseresti, solo la classe in cui è dichiarata può vederla.

Pacchetto privato

Può essere visto e utilizzato solo dal pacchetto in cui è stato dichiarato. Questo è il default in Java (che alcuni vedono come un errore).

protetta

Il pacchetto Private + può essere visto da sottoclassi o membri del pacchetto.

Pubblico

Tutti possono vederlo.

Published

Visibile al di fuori del codice che controllo. (Anche se non è la sintassi Java, è importante per questa discussione).

Il C ++ definisce un livello aggiuntivo chiamato "amico" e meno ne sai e meglio è.

Quando dovresti usare cosa? L'intera idea è l'incapsulamento per nascondere le informazioni. Per quanto possibile, si desidera nascondere i dettagli di come viene fatto qualcosa dai propri utenti. Perché? Perché allora puoi cambiarli più tardi e non infrangere il codice di nessuno. Questo ti consente di ottimizzare, refactoring, riprogettare e correggere bug senza preoccuparti che qualcuno stia usando quel codice che hai appena revisionato.

Quindi, la regola generale è di rendere le cose solo visibili come devono essere. Inizia con privato e aggiungi solo più visibilità se necessario. Rendi pubblico solo ciò che è assolutamente necessario che l'utente sappia, ogni dettaglio che rendi crampi pubblici la tua capacità di ridisegnare il sistema.

Se si desidera che gli utenti siano in grado di personalizzare i comportamenti, piuttosto che rendere pubblici gli interni in modo che possano sovrascriverli, è spesso un'idea migliore spingere quegli intestini in un oggetto e rendere pubblica tale interfaccia. In questo modo possono semplicemente inserire un nuovo oggetto. Ad esempio, se stavi scrivendo un lettore CD e volessi il bit "vai a trovare informazioni su questo CD" personalizzabile, piuttosto che rendere pubblici quei metodi, inseriresti tutte queste funzionalità nel proprio oggetto e renderebbe pubblico solo il tuo oggetto getter / setter . In questo modo essere avidi nell'esporre le tue viscere incoraggia una buona composizione e separazione delle preoccupazioni

Personalmente, rimango solo con "privato" e "pubblico". Molte lingue OO hanno questo. "Protetto" può essere utile, ma è davvero un trucco. Una volta che un'interfaccia è più che privata, è fuori dal tuo controllo e devi cercare nel codice di altre persone per trovare gli usi.

È qui che entra in gioco l'idea di "pubblicato". Cambiare un'interfaccia (refactoring) richiede che tu trovi tutto il codice che lo sta usando e lo cambi anche. Se l'interfaccia è privata, nessun problema. Se è protetto devi trovare tutte le sottoclassi. Se è pubblico devi trovare tutto il codice che usa il tuo codice. A volte questo è possibile, ad esempio se stai lavorando su un codice aziendale che è solo per uso interno, non importa se un'interfaccia è pubblica. Puoi estrarre tutto il codice dal repository aziendale. Ma se un'interfaccia è "pubblicata", se c'è del codice che la utilizza al di fuori del tuo controllo, allora tu verrai disinformato. È necessario supportare tale interfaccia o rischiare di violare il codice. Anche le interfacce protette possono essere considerate pubblicate (motivo per cui non mi preoccupo di proteggere).

Molte lingue trovano la natura gerarchica di pubblico / protetto / privato troppo limitante e non in linea con la realtà. A tal fine c'è il concetto di una classe di tratto , ma questo è un altro spettacolo.


Ecco una versione migliore del tavolo. (Prova futura con una colonna per i moduli.)

spiegazioni

  • Un membro privato è accessibile solo all'interno della stessa classe dichiarata.

  • Un membro senza modificatore di accesso è accessibile solo all'interno di classi nello stesso pacchetto.

  • Un membro protetto è accessibile all'interno di tutte le classi nello stesso pacchetto e in sottoclassi in altri pacchetti.

  • Un membro pubblico è accessibile a tutte le classi (a meno che non risieda in un module che non esporta il pacchetto in cui è dichiarato).

Quale modificatore scegliere?

I modificatori di accesso sono uno strumento che ti aiuta a prevenire l'incapsulamento accidentale (*) . Chiediti se intendi che il membro sia qualcosa che è interno alla classe, al pacchetto, alla gerarchia di classi o non sia interno e scegli il livello di accesso di conseguenza.

Esempi:

  • Probabilmente un long internalCounter field del campo dovrebbe essere privato dato che è mutabile e un dettaglio di implementazione.
  • Una classe che dovrebbe essere istanziata solo in una classe factory (nello stesso pacchetto) dovrebbe avere un costruttore a pacchetto limitato, dal momento che non dovrebbe essere possibile chiamarlo direttamente dall'esterno del pacchetto.
  • Un metodo interno void beforeRender() chiamato right prima del rendering e usato come un hook in sottoclassi dovrebbe essere protetto.
  • Un void saveGame(File dst) che viene chiamato dal codice della GUI dovrebbe essere pubblico.

(*) Che cos'è esattamente l'incapsulamento?


Il tutorial ufficiale potrebbe esserti utile.

            │ Class │ Package │ Subclass │ Subclass │ World
            │       │         │(same pkg)│(diff pkg)│ 
────────────┼───────┼─────────┼──────────┼──────────┼────────
public      │   +   │    +    │    +     │     +    │   +     
────────────┼───────┼─────────┼──────────┼──────────┼────────
protected   │   +   │    +    │    +     │     +    │         
────────────┼───────┼─────────┼──────────┼──────────┼────────
no modifier │   +   │    +    │    +     │          │    
────────────┼───────┼─────────┼──────────┼──────────┼────────
private     │   +   │         │          │          │    

+ : accessible
blank : not accessible

Public Protected Default e private sono modificatori di accesso.

Sono pensati per incapsulare o nascondere e mostrare i contenuti della classe.

  1. La classe può essere pubblica o predefinita
  2. I membri della classe possono essere pubblici, protetti, predefiniti o privati.

Privato non accessibile al di fuori della classe Il valore predefinito è accessibile solo nel pacchetto. Protetto in pacchetto così come ogni classe che lo estende. Il pubblico è aperto a tutti.

Normalmente, le variabili membro sono definite private, ma i metodi membri sono pubblici.


Privato

  • Metodi, Variabili e Costruttori

Metodi, variabili e costruttori dichiarati privati ​​sono accessibili solo all'interno della classe dichiarata.

  • Classe e interfaccia

Il modificatore di accesso privato è il livello di accesso più restrittivo. La classe e le interfacce non possono essere private.

Nota

Le variabili dichiarate private sono accessibili al di fuori della classe se nella classe sono presenti metodi getter pubblici. Variabili, metodi e costruttori che sono dichiarati protetti in una superclasse sono accessibili solo dalle sottoclassi di un altro pacchetto o di qualsiasi classe all'interno del pacchetto della classe dei membri protetti.

protetta

  • Classe e interfaccia

Il modificatore di accesso protetto non può essere applicato alla classe e alle interfacce.

Metodi, i campi possono essere dichiarati protetti, tuttavia i metodi e i campi in un'interfaccia non possono essere dichiarati protetti.

Nota

L'accesso protetto consente alla sottoclasse di utilizzare il metodo o la variabile helper, impedendo al contempo a una classe non correlata di tentare di utilizzarla.

Pubblico

Una classe, un metodo, un costruttore, un'interfaccia, ecc., Dichiarato pubblico, è accessibile da qualsiasi altra classe.

Pertanto è possibile accedere a campi, metodi, blocchi dichiarati all'interno di una classe pubblica da qualsiasi classe appartenente all'universo Java.

  • Pacchetti diversi

Tuttavia, se la classe pubblica a cui stiamo tentando di accedere si trova in un pacchetto diverso, la classe pubblica deve ancora essere importata.

A causa dell'ereditarietà delle classi, tutti i metodi pubblici e le variabili di una classe sono ereditati dalle sue sottoclassi.

Predefinito -Nessuna parola chiave:

Il modificatore di accesso predefinito significa che non dichiariamo esplicitamente un modificatore di accesso per una classe, un campo, un metodo, ecc.

  • All'interno degli stessi pacchetti

Una variabile o un metodo dichiarato senza alcun modificatore del controllo di accesso è disponibile per qualsiasi altra classe nello stesso pacchetto. I campi di un'interfaccia sono implicitamente statici finali pubblici e i metodi in un'interfaccia sono di pubblico dominio.

Nota

Non possiamo sovrascrivere i campi Statici. Se provi a sovrascriverli, non mostra alcun errore, ma non funziona a parte noi.

Risposte correlate

Link di riferimenti

http://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html http://www.tutorialspoint.com/java/java_access_modifiers.htm


La risposta di David fornisce il significato di ciascun modificatore di accesso. Per quanto riguarda il momento in cui usarli, suggerirei di rendere pubbliche tutte le classi e i metodi di ogni classe che sono pensati per uso esterno (la sua API) e tutto il resto privato.

Con il passare del tempo, svilupperai un senso per quando rendere un pacchetto di classi privato e quando dichiarare certi metodi protetti per l'uso in sottoclassi.


Il modificatore di accesso più incompreso in Java è protected . Sappiamo che è simile al modificatore predefinito con un'eccezione in cui le sottoclassi possono vederlo. Ma come? Ecco un esempio che si spera chiarisca la confusione:

  • Supponiamo di avere 2 classi; Father e Son , ciascuno nel proprio pacchetto:

    package fatherpackage;
    
    public class Father
    {
    
    }
    
    -------------------------------------------
    
    package sonpackage;
    
    public class Son extends Father
    {
    
    }
    
  • Aggiungiamo un metodo protetto foo() a Father .

    package fatherpackage;
    
    public class Father
    {
        protected void foo(){}
    }
    
  • Il metodo foo() può essere chiamato in 4 contesti:

    1. All'interno di una classe che si trova nello stesso pacchetto in cui è definito foo() ( fatherpackage ):

      package fatherpackage;
      
      public class SomeClass
      {
          public void someMethod(Father f, Son s)
          {
              f.foo();
              s.foo();
          }
      }
      
    2. All'interno di una sottoclasse, nell'istanza corrente tramite this o super :

      package sonpackage;
      
      public class Son extends Father
      {
          public void sonMethod()
          {
              this.foo();
              super.foo();
          }
      }
      
    3. Su un riferimento il cui tipo è della stessa classe:

      package fatherpackage;
      
      public class Father
      {
          public void fatherMethod(Father f)
          {
              f.foo(); // valid even if foo() is private
          }
      }
      
      -------------------------------------------
      
      package sonpackage;
      
      public class Son extends Father
      {
          public void sonMethod(Son s)
          {
              s.foo();
          }
      }
      
    4. Su un riferimento il cui tipo è la classe genitore e si trova all'interno del pacchetto in cui è definito foo() ( fatherpackage ) [Questo può essere incluso nel contesto n. 1]:

      package fatherpackage;
      
      public class Son extends Father
      {
          public void sonMethod(Father f)
          {
              f.foo();
          }
      }
      
  • Le seguenti situazioni non sono valide.

    1. Su un riferimento il cui tipo è la classe genitore e si trova all'esterno del pacchetto in cui è definito foo() ( fatherpackage ):

      package sonpackage;
      
      public class Son extends Father
      {
          public void sonMethod(Father f)
          {
              f.foo(); // compilation error
          }
      }
      
    2. Una non sottoclasse all'interno di un pacchetto di una sottoclasse (una sottoclasse eredita i membri protetti dal suo genitore e li rende privati ​​di non sottoclassi):

      package sonpackage;
      
      public class SomeClass
      {
          public void someMethod(Son s) throws Exception
          {
              s.foo(); // compilation error
          }
      }
      

  • pubblico - accessibile da qualsiasi punto dell'applicazione.

  • predefinito - accessibile dal pacchetto.

  • protetto - accessibile da pacchetto e sottoclassi in altri pacchetti. anche

  • privato - accessibile solo dalla sua classe.


In brevissimo

  • public : accessibile da ogni luogo.
  • protected : accessibile dalle classi dello stesso pacchetto e delle sottoclassi che risiedono in qualsiasi pacchetto.
  • default (nessun modificatore specificato): accessibile dalle classi dello stesso pacchetto.
  • private : accessibile solo nella stessa classe.

Nota: questo è solo un supplemento per la risposta accettata.

Questo è legato ai Modificatori di accesso Java .

Da Modificatori di accesso Java :

Un modificatore di accesso Java specifica quali classi possono accedere a una determinata classe e i relativi campi, costruttori e metodi. I modificatori di accesso possono essere specificati separatamente per una classe, i suoi costruttori, campi e metodi. I modificatori di accesso Java sono anche a volte indicati nel parlato quotidiano come specificatori di accesso Java, ma il nome corretto è modificatori di accesso Java. Classi, campi, costruttori e metodi possono avere uno dei quattro diversi modificatori di accesso Java:

  • Elemento dell'elenco
  • privato
  • predefinito (pacchetto)
  • protetta
  • pubblico

Dall'accesso di controllo ai tutorial di membri di una classe :

I modificatori del livello di accesso determinano se altre classi possono utilizzare un particolare campo o richiamare un particolare metodo. Esistono due livelli di controllo degli accessi:

  • Al livello più alto: pubblico o privato del pacchetto (nessun modificatore esplicito).
  • A livello di membro: pubblico, privato, protetto o privato del pacchetto (nessun modificatore esplicito).

Una classe può essere dichiarata con il modificatore pubblico, nel qual caso tale classe è visibile a tutte le classi ovunque. Se una classe non ha alcun modificatore (l'impostazione predefinita, nota anche come pacchetto-privato), è visibile solo all'interno del proprio pacchetto

La seguente tabella mostra l'accesso ai membri consentiti da ciascun modificatore.

╔═════════════╦═══════╦═════════╦══════════╦═══════╗
║ Modifier    ║ Class ║ Package ║ Subclass ║ World ║
╠═════════════╬═══════╬═════════╬══════════╬═══════╣
║ public      ║ Y     ║ Y       ║ Y        ║ Y     ║
║ protected   ║ Y     ║ Y       ║ Y        ║ N     ║
║ no modifier ║ Y     ║ Y       ║ N        ║ N     ║
║ private     ║ Y     ║ N       ║ N        ║ N     ║
╚═════════════╩═══════╩═════════╩══════════╩═══════╝

La prima colonna di dati indica se la classe stessa ha accesso al membro definito dal livello di accesso. Come puoi vedere, una classe ha sempre accesso ai propri membri. La seconda colonna indica se le classi nello stesso pacchetto della classe (indipendentemente dalla loro parentela) hanno accesso al membro. La terza colonna indica se le sottoclassi della classe dichiarate all'esterno di questo pacchetto hanno accesso al membro. La quarta colonna indica se tutte le classi hanno accesso al membro.

I livelli di accesso ti influenzano in due modi. Innanzitutto, quando si utilizzano classi provenienti da un'altra fonte, ad esempio le classi nella piattaforma Java, i livelli di accesso determinano quali membri di tali classi possono utilizzare le proprie classi. In secondo luogo, quando si scrive una classe, è necessario decidere quale livello di accesso deve avere ogni variabile membro e ogni metodo della classe.


In realtà è un po 'più complicato di una semplice griglia. La griglia ti dice se è permesso un accesso, ma cosa costituisce esattamente un accesso? Inoltre, i livelli di accesso interagiscono con le classi e l'ereditarietà nidificate in modi complessi.

L'accesso "predefinito" (specificato dall'assenza di una parola chiave) viene anche chiamato package-private . Eccezione: in un'interfaccia, nessun modificatore significa accesso pubblico; i modificatori diversi dal pubblico sono vietati. Le costanti Enum sono sempre pubbliche.

Sommario

È consentito l'accesso a un membro con questo identificatore di accesso?

  • Il membro è private : solo se il membro è definito all'interno della stessa classe del codice chiamante.
  • Il membro è privato del pacchetto: solo se il codice chiamante si trova nel pacchetto che include immediatamente il membro.
  • Il membro è protected : lo stesso pacchetto o se il membro è definito in una superclasse della classe che contiene il codice chiamante.
  • Il membro è public : sì.

A chi si applicano gli specificatori di accesso

Le variabili locali e i parametri formali non possono prendere gli identificatori di accesso. Dal momento che sono intrinsecamente inaccessibili all'esterno secondo le regole dell'ambito, sono effettivamente privati.

Per le classi nell'ambito top, sono consentiti solo public e package-private. Questa scelta progettuale è presumibilmente perché protected e private sarebbero ridondanti a livello di pacchetto (non vi è alcuna ereditarietà dei pacchetti).

Tutti gli specificatori di accesso sono possibili sui membri della classe (costruttori, metodi e funzioni dei membri statici, classi nidificate).

Correlato: Accessibilità della classe Java

Ordine

Gli specificatori di accesso possono essere ordinati rigorosamente

pubblico> protetto> pacchetto-privato> privato

il che significa che il public fornisce il massimo accesso, il minimo private . Qualsiasi riferimento possibile su un membro privato è valido anche per un membro privato del pacchetto; qualsiasi riferimento a un membro privato del pacchetto è valido su un membro protetto e così via. (Dare l'accesso ai membri protetti ad altre classi nello stesso pacchetto è stato considerato un errore).

Gli appunti

  • I metodi di una classe sono autorizzati ad accedere a membri privati ​​di altri oggetti della stessa classe. Più precisamente, un metodo di classe C può accedere a membri privati ​​di C su oggetti di qualsiasi sottoclasse di C. Java non supporta la limitazione dell'accesso per istanza, solo per classe. (Confrontati con Scala, che lo supporta utilizzando private[this] .)
  • È necessario accedere a un costruttore per costruire un oggetto. Pertanto, se tutti i costruttori sono privati, la classe può essere costruita solo dal codice che vive all'interno della classe (in genere metodi di factory statici o inizializzatori di variabili statiche). Allo stesso modo per i costruttori di pacchetti privati ​​o protetti.
    • Solo avere costruttori privati ​​significa anche che la classe non può essere sottoclassata esternamente, dal momento che Java richiede ai costruttori di una sottoclasse di chiamare implicitamente o esplicitamente un costruttore di superclasse. (Può tuttavia contenere una classe nidificata che la sottoclasse).

Classi interne

Devi anche considerare gli ambiti annidati , come le classi interne. Un esempio della complessità è che le classi interne hanno membri, che a loro volta possono prendere modificatori di accesso. Quindi puoi avere una classe privata interna con un membro pubblico; si può accedere al membro? (Vedi sotto). La regola generale è guardare lo scope e pensare in modo ricorsivo per vedere se è possibile accedere ad ogni livello.

Tuttavia, questo è abbastanza complicato, e per i dettagli completi, consultare la specifica del linguaggio Java . (Sì, ci sono stati errori nel compilatore in passato.)

Per un assaggio di come questi interagiscono, considera questo esempio. È possibile "perdere" classi interne private; questo di solito è un avvertimento:

class Test {
    public static void main(final String ... args) {
        System.out.println(Example.leakPrivateClass()); // OK
        Example.leakPrivateClass().secretMethod(); // error
    }
}

class Example {
    private static class NestedClass {
        public void secretMethod() {
            System.out.println("Hello");
        }
    }
    public static NestedClass leakPrivateClass() {
        return new NestedClass();
    }
}

Uscita del compilatore:

Test.java:4: secretMethod() in Example.NestedClass is defined in an inaccessible class or interface
        Example.leakPrivateClass().secretMethod(); // error
                                  ^
1 error

Alcune domande correlate:


Un interfaccia è come un insieme di geni che sono pubblicamente documentati di avere una sorta di effetto: Un test del DNA mi dirà se io li ho - e se lo faccio, posso pubblicamente far sapere che io sono un "vettore "e parte del mio comportamento o stato si conformerà a loro. (Ma naturalmente, potrei avere molti altri geni che forniscono tratti al di fuori di questo ambito.)

Una classe astratta è come l'antenato morto di una specie dello stesso sesso (*): non può essere riportata in vita ma una discendente vivente (cioè non astratta ) eredita tutti i suoi geni.

(*) Per estendere questa metafora, diciamo che tutti i membri della specie vivono alla stessa età. Ciò significa che anche tutti gli antenati di un antenato morto devono essere morti - e allo stesso modo, tutti i discendenti di un antenato vivente devono essere vivi.





java private public protected access-modifiers