Domanda

In Java, ci sono regole precise su quando utilizzare ciascuna di modificatori di accesso, vale a dire il valore di default (pacchetto privato), public, protected e private, pur facendo class e interface e si occupano di eredità?

È stato utile?

Soluzione

Il tutorial ufficiale potrebbe esserti utile .

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

 + : accessible         blank : not accessible

Altri suggerimenti

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

Privato

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

Pacchetto privato

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

Protezione

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

pubblico

Tutti possono vederlo.

Pubblicato

Visibile al di fuori del codice che controllo. (Pur non essendo una sintassi Java, è importante per questa discussione).

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

Quando dovresti usare cosa? L'intera idea è l'incapsulamento per nascondere le informazioni. Per quanto possibile, vuoi nascondere i dettagli di come viene fatto qualcosa ai tuoi utenti. Perché? Perché poi puoi cambiarli in seguito e non violare il codice di nessuno. Ciò ti consente di ottimizzare, riformattare, riprogettare e correggere i bug senza preoccuparti che qualcuno stesse usando quel codice che hai appena revisionato.

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

Se vuoi 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 quelle viscere in un oggetto e rendere pubblica quell'interfaccia. In questo modo possono semplicemente collegare un nuovo oggetto. Ad esempio, se stavi scrivendo un lettore CD e volessi il " vai a trovare informazioni su questo CD " un po 'personalizzabile, piuttosto che rendere pubblici quei metodi avresti messo tutta quella funzionalità nel suo oggetto e reso pubblico solo il tuo oggetto getter / setter. In questo modo essere avari di esporre l'intestino incoraggia una buona composizione e separazione delle preoccupazioni

Personalmente, rimango solo con " private " e "pubblico". Molte lingue OO hanno proprio questo. & Quot; protetto " può essere utile, ma è davvero un imbroglione. 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 è dove l'idea di "pubblicato" entra. La modifica di un'interfaccia (refactoring) richiede la ricerca di tutto il codice che la sta utilizzando e anche la modifica. Se l'interfaccia è privata, non c'è problema. Se è protetto devi cercare tutte le tue sottoclassi. Se è pubblico devi trovare tutto il codice che utilizza 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 sei esagerato. È necessario supportare tale interfaccia o il codice di rottura del rischio. Anche le interfacce protette possono essere considerate pubblicate (motivo per cui non mi preoccupo della protezione).

Molte lingue ritengono che la natura gerarchica di pubblico / protetto / privato sia troppo limitante e non in linea con la realtà. A tal fine esiste il concetto di classe di tratti , ma questo è un altro spettacolo.

Ecco una versione migliore della tabella. (A prova di futuro con una colonna per moduli.)

 Modificatori di accesso Java

Spiegazioni

  • Un membro privato ( i ) è solo accessibile all'interno della stessa classe in cui è stato dichiarato.

  • Un membro senza nessun modificatore di accesso ( j ) è accessibile solo all'interno delle classi nello stesso pacchetto.

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

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


Quale modificatore scegliere?

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

Esempi:

  • Un campo long internalCounter dovrebbe probabilmente essere privato poiché è modificabile e un dettaglio di implementazione.
  • Una classe che dovrebbe essere istanziata solo in una classe factory (nello stesso pacchetto) dovrebbe avere un costruttore con restrizioni di pacchetto, poiché non dovrebbe essere possibile chiamarlo direttamente dall'esterno del pacchetto.
  • È necessario proteggere un metodo void beforeRender () interno chiamato prima del rendering e utilizzato come hook nelle sottoclassi.
  • Un metodo void saveGame (File dst) che viene chiamato dal codice GUI dovrebbe essere pubblico.

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

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

Regola semplice. Inizia dichiarando tutto privato. E poi i progressi verso il pubblico quando sorgono i bisogni e il design lo garantisce.

Quando esponete i membri chiedetevi se state esponendo scelte di rappresentanza o scelte di astrazione. Il primo è qualcosa che vuoi 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 desidera che venga sovrascritto.

Inoltre, usa l'annotazione @Override quando esegui l'override per evitare che le cose si rompano durante il refactoring.

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

Il " default " l'accesso (specificato dall'assenza di una parola chiave) è anche chiamato pacchetto-privato . Eccezione: in un'interfaccia, nessun modificatore significa accesso pubblico; i modificatori diversi dal pubblico sono vietati. Le costanti di Enum sono sempre pubbliche.

Sommario

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

  • Il membro è privato : solo se il membro è definito all'interno della stessa classe del codice chiamante.
  • Il membro è un pacchetto privato: solo se il codice chiamante si trova nel pacchetto che racchiude immediatamente il membro.
  • Il membro è protetto : stesso pacchetto o se il membro è definito in una superclasse della classe contenente il codice chiamante.
  • Il membro è public : Sì.

A cosa si applicano gli specificatori di accesso

Le variabili locali e i parametri formali non possono accettare identificatori di accesso. Poiché sono intrinsecamente inaccessibili all'esterno in base alle regole di scoping, sono effettivamente private.

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

Tutti i parametri di accesso sono possibili sui membri della classe (costruttori, metodi e funzioni statiche dei membri, classi nidificate).

Correlati: Accessibilità della classe Java

Ordine

Gli specificatori di accesso possono essere rigorosamente ordinati

  

pubblico > protetto > pacchetto-privato > privato

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

Note

  • I metodi di una classe sono autorizzati ad accedere a membri privati ??di altri oggetti del 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, ma solo per classe. (Confronta con Scala, che lo supporta usando private [this] .)
  • È necessario l'accesso 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 fabbrica statici o inizializzatori di variabili statici). Allo stesso modo per costruttori di pacchetti privati ??o protetti.
    • Avere solo costruttori privati ??significa anche che la classe non può essere sottoclassata esternamente, poiché Java richiede ai costruttori di una sottoclasse di chiamare implicitamente o esplicitamente un costruttore di superclassi. (Tuttavia, può contenere una classe nidificata che la suddivide in sottoclassi.)

Classi interne

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

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

Per un assaggio di come 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();
    }
}

Output 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:

Come regola generale:

  • privato : ambito della classe.
  • default (o pacchetto-privato ): ambito del pacchetto.
  • protetto : pacchetto scope + child (come pacchetto, ma possiamo sottoclassarlo da pacchetti diversi). Il modificatore protetto mantiene sempre " genitore-figlio " rapporto.
  • public : ovunque.

Di conseguenza, se dividiamo l'accesso in tre diritti:

  • (D) irect (invoca da un metodo all'interno della stessa classe o tramite " questa " sintassi).
  • (R) eference (invoca un metodo utilizzando un riferimento alla classe o tramite la sintassi " punto ").
  • (I) ereditarietà (tramite sottoclasse).

allora abbiamo questa semplice tabella:

+—-———————————————+————————————+———————————+
|                 |    Same    | Different |
|                 |   Package  | Packages  |
+—————————————————+————————————+———————————+
| private         |   D        |           |
+—————————————————+————————————+———————————+
| package-private |            |           |
| (no modifier)   |   D R I    |           |
+—————————————————+————————————+———————————+
| protected       |   D R I    |       I   |
+—————————————————+————————————+———————————+
| public          |   D R I    |    R  I   |
+—————————————————+————————————+———————————+

In breve

  • public : accessibile da qualsiasi luogo.
  • protetto : accessibile dalle classi dello stesso pacchetto e dalle sottoclassi residenti in qualsiasi pacchetto.
  • default (nessun modificatore specificato): accessibile dalle classi dello stesso pacchetto.
  • privato : accessibile solo all'interno della stessa classe.

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

  • Supponiamo che abbiamo 2 classi; Father e Son , ciascuno nel suo 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 è la 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 ed è dentro il 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 ed è esterno il 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 ??per non sottoclassi):

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

Privato

  • Metodi,Variabili e dei Costruttori

Metodi, Variabili e Costruttori che si sono dichiarati private, si può accedere solo all'interno della classe dichiarata stesso.

  • Classe e Interfaccia

Privato modificatore di accesso è il più restrittivo livello di accesso.Classe e le interfacce non possono essere privati.

Nota

Le variabili dichiarate private può essere letta al di fuori della classe, se pubblico i metodi getter sono presenti in classe.Variabili, metodi e costruttori, che sono state dichiarate protette in una superclasse può essere letta solo da sottoclassi in altro pacchetto o qualsiasi altra classe all'interno del pacchetto protetto dei membri della classe.


Protetta

  • Classe e Interfaccia

Protetto modificatore di accesso non può essere applicato alla classe e interfacce.

Metodi, i campi possono essere dichiarati protetti, tuttavia i metodi e i campi di una interfaccia non può essere dichiarata protetta.

Nota

Accesso protetto dà la sottoclasse possibilità di utilizzare il metodo helper o variabile, evitando un nonrelated classe cercando di usarlo.


Pubblico

Una classe, un metodo costruttore, interfaccia, ecc dichiarato il pubblico può accedere da qualsiasi altra classe.

Pertanto, i campi, i metodi, i blocchi dichiarata all'interno di una classe pubblica, accessibile da qualsiasi classe di appartenenza Java Universo.

  • Diversi Pacchetti

Tuttavia, se la classe pubblica si sta tentando di accedere è in un pacchetto differente, quindi la classe pubblica devono ancora essere importati.

A causa di ereditarietà di classe, tutti i metodi e le variabili di una classe vengono ereditati dalle sue sottoclassi.


Default-Nessuna parola chiave:

Di Default modificatore di accesso significa che non si dichiara in modo esplicito un modificatore di accesso per una classe, un campo, un metodo, etc.

  • All'interno del pacchetto stesso

Una variabile o un metodo dichiarato senza alcun modificatore del controllo di accesso è disponibile per tutte le altre classi dello stesso package.I campi in un'interfaccia implicitamente public static final e i metodi di un'interfaccia sono per impostazione predefinita pubblico.

Nota

Non possiamo Ignorare i campi Statici.se si tenta di eseguire l'override non mostra alcun errore ma doesnot di lavoro che abbiamo eccezione.

Relative Risposte

Riferimenti link

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

Privato : accesso limitato alla sola classe

Predefinito (nessun modificatore) : accesso limitato a classe e pacchetto

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

Pubblico : accessibile a classe, pacchetto (tutti) e sottoclassi ... in breve, ovunque.

La differenza si trova nei collegamenti già forniti, ma quale utilizzare di solito dipende dal "Principio della conoscenza minima". Consenti solo la minima visibilità necessaria.

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

Pubblico: È fondamentalmente semplice come puoi accedere da qualsiasi classe sia che si trovi nello stesso pacchetto o meno.

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

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

Per accedere è possibile 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 alla sottoclasse in qualsiasi altro pacchetto. quindi sostanzialmente è predefinito + Ereditato comportamento.

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

Privato: può accedere alla stessa classe.

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

Modificatori di accesso in Java.

I modificatori di accesso Java vengono utilizzati per fornire il controllo dell'accesso in Java.

1. Predefinito:

Accessibile solo alle classi nello stesso pacchetto.

Ad 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 di privato.

2. Pubblico

È possibile accedervi da qualsiasi luogo. (Accesso globale)

Ad 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();
  }
}
  

Output: Ciao

3. Privato

Accessibile solo all'interno della stessa classe.

Se si tenta di accedere a membri privati ??di una classe in un'altra genererà un errore di compilazione. Ad 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

Ad 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();
  }
}
  

Output: Ciao

 Inserisci qui la descrizione dell

Voglio solo affrontare un dettaglio che è estremamente comunemente sbagliato, incluso dalla maggior parte delle risposte in questa pagina. " predefinito " l'accesso (quando non è presente alcun modificatore di accesso) non è sempre uguale al pacchetto-privato . Dipende da quale sia la cosa.

  • I tipi non membri (ovvero classi, enumerazioni, interfacce e tipi di annotazione non dichiarati all'interno di un altro tipo) sono pacchetti privati ??per impostazione predefinita. ( JLS & # 167; 6.6.1 )

  • I membri della classe e i costruttori sono pacchetti privati ??per impostazione predefinita. ( JLS & # 167; 6.6.1 )

  • I costruttori di Enum sono privati ??per impostazione predefinita . (In effetti, i costruttori 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. Altri membri di enum sono pacchetti privati ??per impostazione predefinita. ( JLS & # 167; 8.9 )

  • Tutti i membri delle interfacce e dei tipi di annotazione sono pubblici per impostazione predefinita . (In effetti, i membri delle interfacce e dei tipi di annotazione devono essere pubblici ed è un errore tentare di renderli privati ??o protetti.) (JLS & # 167; 9.3 a 9.5 )

  • pubblico - accessibile da qualsiasi parte dell'applicazione.

  • predefinito - accessibile dal pacchetto.

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

  • privato - accessibile solo dalla sua classe.

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

Visibile solo alla classe ( privato ).

Visibile al mondo ( pubblico ).

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

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 stessa. Il modificatore di accesso privato è il livello di accesso più restrittivo. Classe e interfacce non possono essere private.

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

L'uso 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. dichiarati pubblici sono accessibili da qualsiasi altra classe. Pertanto, campi, metodi, blocchi dichiarati all'interno di una classe pubblica sono accessibili 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 comunque essere importata.

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

Esempio:

public void cal(){

}

Modificatore di accesso protetto - protetto:

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

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

L'accesso protetto offre alla sottoclasse la possibilità di utilizzare il metodo helper o la variabile, impedendo a una classe non correlata di tentare di usarla.

class Van{

    protected boolean speed(){

    }
}

class Car{
    boolean speed(){
    }

}

Questa pagina scrive bene di protetto e amp ; modificatore di accesso predefinito

.... Protetto: il modificatore di accesso protetto è un po 'complicato e puoi dire che è un superset del modificatore di accesso predefinito. I membri protetti sono gli stessi membri predefiniti per quanto riguarda l'accesso allo stesso pacchetto. La differenza è che i membri protetti sono accessibili anche alle sottoclassi della classe in cui viene dichiarato il membro che sono al di fuori del pacchetto in cui è presente la classe genitore.

Ma questi membri protetti sono "accessibili al di fuori del pacchetto solo tramite ereditarietà". cioè puoi accedere direttamente a un membro protetto di una classe nella sua sottoclasse presente in qualche altro pacchetto come se il membro fosse presente nella sottoclasse stessa. Ma quel membro protetto non sarà accessibile nella sottoclasse esterna al pacchetto utilizzando il riferimento della classe genitore. ....

La risposta di David fornisce il significato di ciascun modificatore di accesso. Per quanto riguarda quando 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.

Nel corso del tempo svilupperai un senso per quando rendere alcune classi pacchetti private e quando dichiarare determinati metodi protetti per l'uso in sottoclassi.

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

Questo è legato a Java Modificatori di accesso .

Da Modificatori di accesso Java :

  

Un modificatore di accesso Java specifica quali classi possono accedere a un dato   classe e suoi campi, costruttori e metodi. I modificatori di accesso possono   essere specificato separatamente per una classe, i suoi costruttori, i campi e   metodi. I modificatori di accesso a Java sono talvolta citati quotidianamente   discorso come identificatori di accesso Java, ma il nome corretto è accesso Java   modificatori. Classi, campi, costruttori e metodi possono avere uno di   quattro diversi modificatori di accesso Java:

     
      
  • Voce di elenco
  •   
  • privati ??
  •   
  • default (pacchetto)
  •   
  • protetto
  •   
  • pubblico
  •   

Da Controllo dell'accesso ai membri di una classe : tutorial

  

I modificatori del livello di accesso determinano se altre classi possono usare a   campo particolare o invocare un metodo particolare. Ci sono due livelli   di controllo dell'accesso:

     
      
  • Al livello superiore & # 8212; public o package-private (nessun modificatore esplicito).
  •   
  • A livello di membro & # 8212; pubblico, privato, protetto o pacchetto-privato (nessun modificatore esplicito).
  •   
     

Una classe può essere dichiarata con il modificatore pubblico, nel qual caso quello   la classe è visibile a tutte le classi ovunque. Se una classe non ha modificatore   (il valore predefinito, noto anche come pacchetto-privato), è visibile solo   nel suo pacchetto

     

La tabella seguente mostra l'accesso ai membri consentito da ciascuno   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   il membro definito dal livello di accesso. Come puoi vedere, una classe sempre   ha accesso ai propri membri. La seconda colonna indica se   classi nello stesso pacchetto della classe (indipendentemente dalla loro   parentage) hanno accesso al membro. La terza colonna indica   se sono presenti sottoclassi della classe dichiarata all'esterno di questo pacchetto   accesso al membro. La quarta colonna indica se tutte le classi   avere accesso al membro.

     

I livelli di accesso ti influenzano in due modi. Innanzitutto, quando usi le classi   provengono da un'altra fonte, come le classi nella piattaforma Java,   i livelli di accesso determinano quali membri di quelle classi sono tuoi   le classi possono usare. Secondo, quando scrivi una lezione, devi decidere   quale livello di accesso ogni variabile membro e ogni metodo nella tua classe   dovrebbe avere.

Default protetti pubblici e privati ??sono modificatori di accesso.

Sono pensati per l'incapsulamento o per 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.

Il privato non è accessibile al di fuori della classe L'impostazione predefinita è accessibile solo nel pacchetto. Protetto nel pacchetto e in ogni classe che lo estende. Il pubblico è aperto a tutti.

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

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

Supponiamo che tu sia uno studente in un'università e che tu abbia un amico che verrà 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 cammina nel campus può guardare la statua senza il permesso dell'università. Questo rende la statua come PUBBLICA.

  • Successivamente, vuoi portare il tuo amico nel tuo dormitorio, ma per questo devi registrarlo come visitatore. Ciò significa che ottiene un pass di accesso (che è uguale al tuo) per entrare in vari edifici del campus. Ciò renderebbe la sua carta di accesso come PROTETTA.

  • Il tuo amico vuole accedere al campus WiFi ma non ha le credenziali per farlo. L'unico modo in cui può collegarsi online è se condividi il tuo login con lui. (Ricorda, ogni studente che va all'università possiede anche queste credenziali di accesso). Ciò renderebbe le tue credenziali di accesso come NESSUN MODIFICATORE .

  • Infine, il tuo amico vuole leggere il tuo rapporto sullo stato di avanzamento per il semestre 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 come PRIVATE.

Spero che questo aiuti!

Quando stai pensando ai modificatori di accesso, pensaci in questo modo (vale sia per variabili che 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 default e protected

default - > Nessuna parola chiave del modificatore di accesso è presente. Ciò significa che è disponibile rigorosamente all'interno del pacchetto della classe. Da nessuna parte al di fuori di quel pacchetto è possibile accedervi.

protetto - > Leggermente meno rigoroso di default e oltre alle stesse classi di pacchetti è possibile accedervi da sottoclassi al di fuori del pacchetto che viene dichiarato.

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

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

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

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

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

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

Se al contrario imposti tutto come pubblico non sarà chiaro cosa dovrebbe o non dovrebbe essere accessibile, il che potrebbe portare a scrivere molto javadoc (che non impone nulla tramite il compilatore ...).

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