tutorial - private package java




Qual è la differenza tra pubblico, protetto, pacchetto-privato e privato in Java? (16)

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

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à?


(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?


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.


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.

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:


Regola facile Inizia con dichiarare tutto privato. E poi progredire verso il pubblico man mano che sorgono i bisogni e il design lo garantisce.

Quando esponi i membri chiedi a te stesso se stai esponendo le scelte di rappresentazione o le scelte di astrazione. Il primo è qualcosa che si vuole evitare in quanto introdurrà troppe dipendenze dalla rappresentazione reale piuttosto che dal suo comportamento osservabile.

Come regola generale, cerco di evitare di sovrascrivere le implementazioni del metodo tramite la sottoclasse; è troppo facile rovinare la logica. Dichiarare metodi protetti astratti se si intende farlo sovrascrivere.

Inoltre, utilizzare l'annotazione @ Override quando si esegue l'override per evitare che le cose si rompano quando si effettua il refactoring.


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(){
    }

}

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. ....


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


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.


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.


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.


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 ...).


Voglio solo affrontare un dettaglio che è estremamente comunemente sbagliato, inclusa la maggior parte delle risposte in questa pagina. L'accesso "predefinito" (quando nessun modificatore di accesso è presente) non è sempre uguale al pacchetto privato . Dipende da cosa è la cosa.

  • I tipi non membri (vale a dire classi, enumerazioni, interfacce e tipi di annotazione non dichiarati all'interno di un altro tipo) sono pacchetti-privati ​​per impostazione predefinita. ( JLS §6.6.1 )

  • I membri della classe e i costruttori sono pacchetti-privati ​​per impostazione predefinita. ( JLS §6.6.1 )

  • I costruttori Enum sono privati ​​per impostazione predefinita . (In effetti, i controli di enum devono essere privati, ed è un errore cercare di renderli pubblici o protetti). Le costanti Enum sono pubbliche e non consentono alcun identificatore di accesso. Gli altri membri dell'enumerazione sono privati ​​dei pacchetti per impostazione predefinita. ( JLS §8.9 )

  • Tutti i membri di interfacce e tipi di annotazione sono pubblici per impostazione predefinita . (In effetti, i membri di interfacce e tipi di annotazione devono essere pubblici, ed è un errore cercare di renderli privati ​​o protetti.) ( JLS §9.3-9.5 )


                | 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         |       ✔       |     ✘     |       ✘       |   ✘    




access-modifiers