modificateurs - public static java




Quelle est la différence entre public, protected, package-private et private en Java? (16)

Privé

  • Méthodes, variables et constructeurs

Les méthodes, variables et constructeurs déclarés privés ne sont accessibles que dans la classe déclarée elle-même.

  • Classe et interface

Le modificateur d'accès privé est le niveau d'accès le plus restrictif. La classe et les interfaces ne peuvent pas être privées.

Remarque

Les variables déclarées privées sont accessibles en dehors de la classe si des méthodes de lecture publiques sont présentes dans la classe. Les variables, méthodes et constructeurs déclarés protégés dans une superclasse ne sont accessibles qu'aux sous-classes d'un autre package ou de n'importe quelle classe du package de la classe des membres protégés.

Protégé

  • Classe et interface

Le modificateur d'accès protégé ne peut pas être appliqué à la classe et aux interfaces.

Les méthodes et les champs peuvent être déclarés protégés. Toutefois, les méthodes et les champs d'une interface ne peuvent pas être déclarés protégés.

Remarque

L'accès protégé donne à la sous-classe une chance d'utiliser la méthode d'assistance ou la variable, tout en empêchant une classe non apparentée d'essayer de l'utiliser.

Publique

Une classe, une méthode, un constructeur, une interface, etc. déclarée publique peut être accédée depuis n'importe quelle autre classe.

Par conséquent, les champs, méthodes et blocs déclarés dans une classe publique sont accessibles à partir de toute classe appartenant à l'univers Java.

  • Différents forfaits

Toutefois, si la classe publique à laquelle vous essayez d'accéder se trouve dans un package différent, elle doit toujours être importée.

En raison de l'héritage de classe, toutes les méthodes et variables publiques d'une classe sont héritées par ses sous-classes.

Par défaut -Pas de mot-clé:

Le modificateur d'accès par défaut signifie que nous ne déclarons pas explicitement un modificateur d'accès pour une classe, un champ, une méthode, etc.

  • Dans les mêmes forfaits

Une variable ou une méthode déclarée sans modificateur de contrôle d'accès est disponible pour toute autre classe du même package. Les champs d'une interface sont implicitement publics, statique final et les méthodes d'une interface sont par défaut publiques.

Remarque

Nous ne pouvons pas remplacer les champs statiques. Si vous essayez de les remplacer, aucune erreur ne se produit, mais cela ne fonctionne pas ce que nous exceptons.

Réponses connexes

Liens de références

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

En Java, existe-t-il des règles claires sur le moment d'utilisation de chacun des modificateurs d'accès, à savoir le paramètre par défaut (package private), public , protected et private , tout en rendant la class et l' interface et en traitant l'héritage?


(Mise en garde: je ne suis pas un programmeur Java, je suis un programmeur Perl. Perl n’a aucune protection formelle, c’est peut-être pourquoi je comprends si bien le problème :))

Privé

Comme on pourrait le penser, seule la classe dans laquelle il est déclaré peut le voir.

Paquet Privé

Ne peut être vu et utilisé que par le paquet dans lequel il a été déclaré. C'est le défaut en Java (ce que certains voient comme une erreur).

Protégé

Le paquet Private + peut être vu par les sous-classes ou les membres du paquet.

Publique

Tout le monde peut le voir.

Published

Visible en dehors du code que je contrôle. (Bien que la syntaxe ne soit pas Java, il est important pour cette discussion).

C ++ définit un niveau supplémentaire appelé "ami" et moins vous en savez, mieux ce sera.

Quand devriez-vous utiliser quoi? L'idée est d'encapsuler pour cacher des informations. Autant que possible, vous souhaitez masquer le détail de la procédure à suivre par vos utilisateurs. Pourquoi? Parce qu'alors vous pouvez les changer plus tard et ne pas casser le code de personne. Cela vous permet d’optimiser, de refactoriser, de repenser et de corriger les bogues sans vous inquiéter du fait que quelqu'un utilisait ce code que vous venez de réviser.

Donc, la règle est de rendre les choses aussi visibles qu’elles doivent être. Commencez avec privé et ajoutez seulement plus de visibilité au besoin. Ne rendez public que ce qui est absolument nécessaire pour que l'utilisateur sache, chaque détail rendu public restreint votre capacité à repenser le système.

Si vous souhaitez que les utilisateurs puissent personnaliser les comportements plutôt que de rendre publics les éléments internes afin de pouvoir les remplacer, il est souvent préférable de placer ces entrailles dans un objet et de rendre cette interface publique. De cette façon, ils peuvent simplement brancher un nouvel objet. Par exemple, si vous écriviez un lecteur de CD et que vous souhaitiez personnaliser le bit "rechercher des informations sur ce CD", plutôt que de rendre ces méthodes publiques, vous mettriez toutes ces fonctionnalités dans son propre objet et ne feriez que votre objet getter / setter public. . De cette façon, être avare d'exposer vos tripes encourage une bonne composition et la séparation des préoccupations

Personnellement, je m'en tiens aux mots "privé" et "public". Beaucoup de langues OO ont juste ça. "Protégé" peut être pratique, mais c'est vraiment une triche. Une fois qu'une interface est plus que privée, elle est hors de votre contrôle et vous devez chercher dans le code d'autres personnes pour trouver des utilisations.

C’est là que l’idée de "publié" entre en jeu. Changer une interface (la refactoriser) nécessite que vous trouviez tout le code qui l’utilise et que vous le changiez aussi. Si l'interface est privée, bon pas de problème. Si c'est protégé, vous devez aller chercher toutes vos sous-classes. Si c'est public, vous devez aller chercher tout le code qui utilise votre code. Cela est parfois possible. Par exemple, si vous travaillez sur un code d'entreprise destiné uniquement à un usage interne, peu importe si une interface est publique. Vous pouvez extraire tout le code du référentiel de l'entreprise. Mais si une interface est "publiée", si du code l'utilise en dehors de votre contrôle, vous êtes bloqué. Vous devez prendre en charge cette interface ou ce code de rupture de risque. Même les interfaces protégées peuvent être considérées comme publiées (c'est pourquoi je ne me soucie pas de protéger).

Beaucoup de langues trouvent la nature hiérarchique de public / protégé / privé trop limitative et non conforme à la réalité. À cette fin, il y a le concept d'une classe de trait , mais c'est un autre spectacle.


En règle générale:

  • private : portée de classe.
  • default (ou package-private ): étendue du package.
  • protected : package scope + child (comme package, mais nous pouvons le sous-classer à partir de différents packages). Le modificateur protected conserve toujours la relation "parent-enfant".
  • public : partout.

Par conséquent, si nous divisons le droit d'accès en trois droits:

  • (D) irect (invoquer depuis une méthode de la même classe).
  • (R) eference (invoquer une méthode en utilisant une référence à la classe ou via la syntaxe "dot").
  • (I) héritage (via sous- classement ).

alors nous avons ce tableau simple:

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

En très court

  • public : accessible de partout.
  • protected : accessible par les classes du même package et les sous-classes résidant dans n'importe quel package.
  • default (aucun modificateur spécifié): accessible par les classes du même package.
  • private : accessible dans la même classe uniquement.

Le modificateur d'accès le plus mal compris en Java est protected . Nous savons qu'il est similaire au modificateur par défaut, à une exception près, où les sous-classes peuvent le voir. Mais comment? Voici un exemple qui, espérons-le, clarifie la confusion:

  • Supposons que nous ayons 2 classes; Father et Son , chacun dans son propre paquet:

    package fatherpackage;
    
    public class Father
    {
    
    }
    
    -------------------------------------------
    
    package sonpackage;
    
    public class Son extends Father
    {
    
    }
    
  • Ajoutons une méthode protégée foo() à Father .

    package fatherpackage;
    
    public class Father
    {
        protected void foo(){}
    }
    
  • La méthode foo() peut être appelée dans 4 contextes:

    1. Dans une classe située dans le même package que celui où foo() est défini ( fatherpackage ):

      package fatherpackage;
      
      public class SomeClass
      {
          public void someMethod(Father f, Son s)
          {
              f.foo();
              s.foo();
          }
      }
      
    2. Dans une sous-classe, sur l'instance actuelle via this ou super :

      package sonpackage;
      
      public class Son extends Father
      {
          public void sonMethod()
          {
              this.foo();
              super.foo();
          }
      }
      
    3. Sur une référence dont le type est la même 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. Sur une référence dont le type est la classe parente et qui se trouve à l' intérieur du package, où foo() est défini ( fatherpackage ) [Ceci peut être inclus dans le contexte non. 1]:

      package fatherpackage;
      
      public class Son extends Father
      {
          public void sonMethod(Father f)
          {
              f.foo();
          }
      }
      
  • Les situations suivantes ne sont pas valides.

    1. Sur une référence dont le type est la classe parente et en dehors du package, où foo() est défini ( fatherpackage ):

      package sonpackage;
      
      public class Son extends Father
      {
          public void sonMethod(Father f)
          {
              f.foo(); // compilation error
          }
      }
      
    2. Une non-sous-classe à l'intérieur d'un package d'une sous-classe (une sous-classe hérite des membres protégés de son parent et les rend privés à des non-sous-classes):

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

Les modificateurs d'accès sont là pour restreindre l'accès à plusieurs niveaux.

Public: C'est aussi simple que vous pouvez accéder depuis n'importe quelle classe, que cela soit dans le même paquet ou non.

Pour accéder si vous êtes dans le même package, vous pouvez y accéder directement, mais si vous êtes dans un autre package, vous pouvez créer un objet de la classe.

Par défaut: il est accessible dans le même package à partir de n'importe quelle classe de package.

Pour y accéder, vous pouvez créer un objet de la classe. Mais vous ne pouvez pas accéder à cette variable en dehors du package.

Protégé: vous pouvez accéder aux variables du même package ainsi qu'aux sous-classes de tout autre package. Donc, fondamentalement, il s’agit du comportement par défaut + hérité .

Pour accéder au champ protégé défini dans la classe de base, vous pouvez créer un objet de classe enfant.

Privé: il peut être accès dans la même classe.

Dans les méthodes non statiques, vous pouvez accéder directement à cause de cette référence (également dans les constructeurs), mais pour accéder aux méthodes statiques, vous devez créer un objet de la classe.


Voici une meilleure version de la table. (Preuve future avec une colonne pour les modules.)

Des explications

  • Un membre privé ( i ) n'est accessible que dans la même classe que celle déclarée.

  • Un membre sans modificateur d'accès ( j ) est uniquement accessible dans les classes du même package.

  • Un membre protégé ( k ) est accessible dans toutes les classes du même package et dans les sous-classes d'autres packages.

  • Un membre public ( l ) est accessible à toutes les classes (à moins qu'il ne réside dans un module qui n'exporte pas le package dans lequel il est déclaré).

Quel modificateur choisir?

Access modifiers est un outil destiné à vous aider à prévenir l’encapsulation accidentelle (*) . Demandez-vous si vous voulez que le membre soit quelque chose qui soit interne à la classe, au package, à la hiérarchie de la classe ou pas du tout interne, et choisissez le niveau d'accès en conséquence.

Exemples:

  • Un champ long internalCounter devrait probablement être privé car il est modifiable et un détail d'implémentation.
  • Une classe qui ne devrait être instanciée que dans une classe fabrique (dans le même package) devrait avoir un constructeur de package restreint, car il ne devrait pas être possible de l'appeler directement de l'extérieur du package.
  • Une méthode interne void beforeRender() appelée juste avant le rendu et utilisée comme raccord dans des sous-classes doit être protégée.
  • Une void saveGame(File dst) appelée à partir du code de l'interface graphique doit être publique.

(*) Qu'est-ce que l'encapsulation exactement?


Le tutoriel officiel peut vous être utile.

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

+ : accessible
blank : not accessible

Modificateurs d'accès en Java.

Les modificateurs d'accès Java sont utilisés pour fournir un contrôle d'accès en Java.

1. Par défaut:

Accessible aux classes dans le même package uniquement.

Par exemple,

// 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
  }
}

Cet accès est plus restreint que public et protégé, mais moins restreint que privé.

2. publique

Peut être accessible de n'importe où. (Accès global)

Par exemple,

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

Sortie: Bonjour

3. Privé

Accessible uniquement dans la même classe.

Si vous essayez d'accéder à des membres privés d'une classe sur une autre, une erreur de compilation sera générée. Par exemple,

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. protégé

Accessible uniquement aux classes du même package et aux sous-classes

Par exemple,

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

Sortie: Bonjour


Privé : accès limité à la classe seulement

Par défaut (pas de modificateur) : accès limité à la classe et au package

Protected : accès limité aux classes, packages et sous-classes (packages internes et externes)

Public : Accessible aux classes, aux packages (tous) et aux sous-classes ... En bref, partout.


Visible à l'emballage. Le défaut. Aucun modificateur n'est nécessaire.

Visible seulement par la classe ( privé ).

Visible au monde ( public ).

Visible pour le package et toutes les sous-classes ( protégées ).

Les variables et les méthodes peuvent être déclarées sans aucun modificateur appelé. Exemples par défaut:

String name = "john";

public int age(){
    return age;
}

Modificateur d'accès privé - privé:

Les méthodes, les variables et les constructeurs déclarés privés ne sont accessibles que dans la classe déclarée elle-même. Le modificateur d'accès privé est le niveau d'accès le plus restrictif. La classe et les interfaces ne peuvent pas être privées.

Les variables déclarées privées sont accessibles en dehors de la classe si des méthodes de lecture publiques sont présentes dans la classe.

L'utilisation du modificateur private est le moyen principal par lequel un objet s'encapsule et cache les données du monde extérieur.

Exemples:

Public class Details{

    private String name;

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

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

Modificateur d'accès public - public:

Une classe, une méthode, un constructeur, une interface, etc. déclarée publique peut être accessible à partir de toute autre classe. Par conséquent, les champs, les méthodes et les blocs déclarés dans une classe publique sont accessibles à partir de toute classe appartenant à l'univers Java.

Toutefois, si la classe publique à laquelle vous essayez d'accéder se trouve dans un package différent, elle doit toujours être importée.

En raison de l'héritage de classe, toutes les méthodes et variables publiques d'une classe sont héritées par ses sous-classes.

Exemple:

public void cal(){

}

Modificateur d'accès protégé - protégé:

Les variables, méthodes et constructeurs déclarés protégés dans une superclasse ne sont accessibles qu'aux sous-classes d'un autre package ou de toute classe du package de la classe des membres protégés.

Le modificateur d'accès protégé ne peut pas être appliqué à la classe et aux interfaces. Les méthodes et les champs peuvent être déclarés protégés. Toutefois, les méthodes et les champs d'une interface ne peuvent pas être déclarés protégés.

L'accès protégé donne à la sous-classe une chance d'utiliser la méthode d'assistance ou la variable, tout en empêchant une classe non apparentée d'essayer de l'utiliser.

class Van{

    protected boolean speed(){

    }
}

class Car{
    boolean speed(){
    }

}

Je veux juste aborder un détail qui est extrêmement souvent erroné, y compris par la plupart des réponses sur cette page. L'accès "par défaut" (en l'absence de modificateur d'accès) n'est pas toujours identique à package-private . Cela dépend de ce que la chose est.

  • Les types non membres (c'est-à-dire les classes, les énumérations, les interfaces et les types d'annotation non déclarés dans un autre type) sont paquet-private par défaut. ( JLS §6.6.1 )

  • Les membres de classe et les constructeurs sont package-private par défaut. ( JLS §6.6.1 )

  • Les constructeurs Enum sont privés par défaut . (En effet, les enum constructeurs doivent être privés, et tenter de les rendre publics ou protégés est une erreur.) Les constantes Enum sont publiques et n'autorisent aucun spécificateur d'accès. Les autres membres des énumérations sont package-private par défaut. ( JLS §8.9 )

  • Tous les membres des types d'interface et d'annotation sont publics par défaut . (En effet, les membres des interfaces et des types d’annotation doivent être publics, et essayer de les rendre privés ou protégés est une erreur.) ( JLS §9.3 à 9.5 )


Lorsque vous songez aux modificateurs d’accès, réfléchissez-y de la manière suivante (s’applique aux variables et aux méthodes ):

public-> accessible de partout
private-> accessible uniquement dans la même classe où il est déclaré

Maintenant , la confusion se pose quand il s'agit defaultetprotected

default-> Aucun mot clé de modificateur d'accès n'est présent. Cela signifie qu'il est disponible strictement dans le package de la classe. Nulle part en dehors de ce paquet, il peut être consulté.

protected-> Légèrement moins strict que defaultles mêmes classes de paquetages, il est accessible aux sous-classes extérieures au paquetage déclaré.


Note: Ceci est juste un supplément pour la réponse acceptée.

Ceci est lié aux modificateurs d'accès Java .

Depuis les modificateurs d'accès Java :

Un modificateur d'accès Java spécifie les classes pouvant accéder à une classe donnée ainsi que ses champs, ses constructeurs et ses méthodes. Les modificateurs d'accès peuvent être spécifiés séparément pour une classe, ses constructeurs, ses champs et ses méthodes. Les modificateurs d'accès Java sont parfois appelés dans la parole quotidienne les spécificateurs d'accès Java, mais le nom correct est celui de modificateurs d'accès Java. Les classes, les champs, les constructeurs et les méthodes peuvent avoir l'un des quatre modificateurs d'accès Java suivants:

  • Élément de liste
  • privé
  • default (package)
  • protégé
  • Publique

De Contrôle de l' accès aux membres d'une classe tutoriels:

Les modificateurs de niveau d'accès déterminent si d'autres classes peuvent utiliser un champ particulier ou invoquer une méthode particulière. Il existe deux niveaux de contrôle d'accès:

  • Au niveau supérieur - public ou package-private (pas de modificateur explicite).
  • Au niveau du membre: public, privé, protégé ou paquet-privé (pas de modificateur explicite).

Une classe peut être déclarée avec le modificateur public, auquel cas cette classe est visible par toutes les classes du monde entier. Si une classe n'a pas de modificateur (la valeur par défaut, également appelée package-private), elle n'est visible que dans son propre package.

Le tableau suivant montre l'accès aux membres autorisé par chaque modificateur.

╔═════════════╦═══════╦═════════╦══════════╦═══════╗
║ 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 première colonne de données indique si la classe elle-même a accès au membre défini par le niveau d'accès. Comme vous pouvez le constater, une classe a toujours accès à ses propres membres. La deuxième colonne indique si les classes du même package que la classe (quelle que soit leur parenté) ont accès au membre. La troisième colonne indique si les sous-classes de la classe déclarées en dehors de ce package ont accès au membre. La quatrième colonne indique si toutes les classes ont accès au membre.

Les niveaux d'accès vous affectent de deux manières. Tout d'abord, lorsque vous utilisez des classes provenant d'une autre source, telles que les classes de la plateforme Java, les niveaux d'accès déterminent les membres de ces classes que vos propres classes peuvent utiliser. Deuxièmement, lorsque vous écrivez une classe, vous devez décider du niveau d'accès que chaque variable membre et chaque méthode de votre classe doivent avoir.


Tout est une question d' encapsulation (ou, comme Joe Phillips l'a dit, le moins de connaissances ).

Commencez par le plus restrictif (privé) et voyez si vous avez besoin ultérieurement de modificateurs moins restrictifs.

Nous utilisons tous des modificateurs de méthode et de membre tels que privé, public, ... mais une chose que trop peu de développeurs font est d'utiliser des packages pour organiser le code de manière logique.

Par exemple: Vous pouvez placer des méthodes de sécurité sensibles dans un package "sécurité". Ensuite, placez une classe publique qui accède à une partie du code lié à la sécurité dans ce package, mais conservez le package des autres classes de sécurité privé . Ainsi, les autres développeurs ne pourront utiliser la classe accessible au public qu'en dehors de ce paquetage (à moins qu'ils ne modifient le modificateur). Ce n'est pas une fonctionnalité de sécurité, mais guidera l' utilisation.

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

Une autre chose est que les classes qui dépendent beaucoup les unes des autres peuvent se retrouver dans le même package et éventuellement être refactorisées ou fusionnées si la dépendance est trop forte.

Au contraire, si vous définissez tout comme public, vous ne saurez pas clairement ce qui devrait ou ne devrait pas être consulté, ce qui pourrait conduire à l'écriture de nombreux javadoc (ce qui n'impose rien via le compilateur ...).


                | 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