Contacts

Quel modificateur d'accès peut être appliqué au package. Modificateurs d'accès. Privé, protégé, par défaut, public. Contrôle d'accès et héritage

Ici, nous allons essayer de couvrir presque tous les cas d'utilisation de modificateurs d'accès. Les seules exceptions sont leur utilisation pour imbriquées ( imbriqué) et interne ( intérieur), ainsi que pour les interfaces, puisque nous n'avons pas encore abordé ces sujets.

Les classes et packages utilisés en conjonction avec les modificateurs d'accès servent de moyens d'encapsulation, c'est-à-dire de moyens de cacher les détails d'implémentation derrière une interface simple.

Les modificateurs d'accès peuvent être appliqués à la fois aux classes et à leurs membres - champs et méthodes. Il y a quatre modificateurs d'accès au total, et ici nous en donnerons une brève description, puis nous examinerons chacun en détail.

  • Publique- tout composant déclaré comme Publique, accessible depuis n'importe quel code
  • protégé- permet l'accès au composant au sein du package et des classes de descendants
  • privé- permet d'accéder aux composants au sein de la classe
  • défaut(pas de mot clé) - Autorise l'accès aux composants dans le package

Les classes héritées sont des classes héritées d'une classe. Nous n'avons pas encore étudié l'héritage.

Accès aux cours

Par défaut, les classes de niveau supérieur sont disponibles dans le package dans lequel elles sont définies.... Cependant, si la classe de niveau supérieur est déclarée comme Publique alors il est disponible partout (ou partout où le package lui-même est disponible). Nous avons limité cette instruction aux classes de niveau supérieur car les classes peuvent être déclarées comme membres d'autres classes. Puisque ces classes internes sont membres de la classe, elles obéissent aux règles de contrôle d'accès aux membres de la classe..

Accéder aux membres de la classe

Les membres de la classe sont toujours disponibles dans le corps de la classe. Défaut les membres de la classe sont également disponibles dans le package dans lequel la classe est définie.

Modificateur public

Pour une classe qui n'est pas imbriquée, seul l'un des deux niveaux d'accès possibles peut être spécifié : défaut et Publique . Lorsque la classe est déclarée comme Publique, ça devrait être le seul Publique la classe déclarée dans le fichier et le nom du fichier doivent correspondre au nom de la classe.

Comment Publique les classes, les champs, les méthodes et les constructeurs peuvent être déclarés.

Modificateur protégé

Nous examinerons de plus près ce modificateur dans le sujet de l'héritage de classe. Si l'héritage n'est pas utilisé, alors ce modificateur fonctionne, tout comme le modificateur par défaut.

La seule chose que l'on peut dire brièvement maintenant est que les composants déclarés comme protégé aura accès n'importe quelle classe enfant de n'importe quel package ou n'importe quelle classe du même package.

Comment protégé les champs, les méthodes, les constructeurs, les classes imbriquées et les interfaces imbriquées peuvent être déclarés.

protégé .

Modificateur privé

C'est le modificateur le plus restrictif en termes de restriction d'accès. Articles déclarés comme privé ne sont accessibles qu'au sein de la même classe et à personne en dehors de la classe.

Comment privé les champs, les méthodes, les constructeurs, les classes imbriquées et les interfaces imbriquées peuvent être déclarés.

Les classes et interfaces de niveau supérieur ne peuvent pas être déclarées comme privé .

Fondamentalement, les modificateurs d'accès sont un sujet simple, mais nous y reviendrons plus tard. Alors que ce n'était qu'une connaissance. Et maintenant un peu de pratique...

J'ai créé les classes Mod02.java, DefMod.java, ProMod.java et PrvMod.java qui appartiennent au package pro.java.pkg002, ainsi que la classe PubMod.java, qui appartient au package pro.java.pkg003. Ensuite, je vais juste donner des captures d'écran de ces classes et du résultat du programme :

Nous parlerons des modificateurs : que sont les modificateurs, les scopes, les modificateurs pour les classes, les champs, les méthodes. Je pense que ce ne sera pas ennuyeux.

Modificateurs en Java Sont des mots-clés qui donnent à une classe, un champ de classe ou une méthode certaines propriétés.

Pour indiquer la visibilité d'une classe de ses méthodes et champs, il existe 4 modificateurs d'accès :

  • privé les membres de la classe ne sont accessibles qu'à l'intérieur de la classe ;
  • package-private ou par défaut (par défaut) les membres de la classe sont visibles à l'intérieur du package ;
  • protégé les membres de classe sont disponibles dans le package et dans les classes dérivées ;
  • Publique les membres de la classe sont disponibles pour tout le monde.

Si vous vous souvenez, à la fin, alors que nous importions déjà la classe Cat, nous avions encore une erreur de compilation.

Le fait est que nous n'avons enregistré aucun modificateur d'accès à nos champs et méthodes, et qu'ils ont une propriété par défaut (les membres de la classe sont visibles à l'intérieur du package). Pour corriger l'erreur de compilation de notre code et enfin l'exécuter, nous devons rendre notre constructeur et nos méthodes publics. Ensuite, ils peuvent être appelés à partir d'autres packages.

Vous pouvez commencer à vous demander : à quoi sert tout cela ? Pourquoi ne pas rendre le code visible à partir de n'importe quel package ou classe, mais avoir besoin de différencier l'accès ? Ces questions disparaîtront d'elles-mêmes lorsque viendra le temps d'écrire des projets complexes et lourds. Maintenant, lorsque nous écrivons des applications dont les fonctionnalités sont limitées à une ou deux classes, il semble que cela n'ait aucun sens de limiter quoi que ce soit.

Imaginez que vous ayez une classe qui affiche un objet produit. Par exemple une voiture. La voiture peut avoir un prix. Vous avez créé un champ de prix et de nombreux autres champs, un ensemble de méthodes responsables de la fonctionnalité. Tout semble être bon. Votre voiture de classe fait partie d'un énorme projet et tout le monde est content. Mais disons que quelqu'un, par erreur ou volontairement, a instancié la classe de voiture et fixé un prix négatif. Comment un produit peut-il avoir un prix négatif ? C'est un exemple très primitif et il est peu probable qu'il se produise dans la vraie vie, mais je pense que l'idée est claire. Parfois, vous devez donner accès non pas directement, mais via certaines méthodes. Il se peut que le code soit responsable de la fonctionnalité d'un autre code et que vous ne souhaitiez pas que quelqu'un modifie et édite une partie du vôtre. Pour tout cela, il y a une restriction d'accès.

Le modificateur d'accès pour les constructeurs, les méthodes et les champs peut être n'importe quoi. Une classe ne peut être que publique ou par défaut, et il ne peut y avoir qu'une seule classe publique dans un fichier.

Pour l'instant, il y en aura assez sur les modificateurs d'accès. Dans l'article "Programmation orientée objet", nous en parlerons plus en détail, mais parlons maintenant d'autres modificateurs dont, d'ailleurs, il y en a beaucoup.

Maintenant, le prochain modificateur est statique... Il peut être utilisé devant une méthode, un champ et même une classe lorsque nous voulons déclarer une classe imbriquée. En Java, vous pouvez écrire des classes à l'intérieur d'autres classes, et si le modificateur avant la classe est à l'intérieur de la classe statique, alors une telle classe est appelée imbriquée, s'il existe un autre modificateur ou par défaut, une telle classe est appelée interne. Il y aura un article séparé sur les classes imbriquées et internes, car tout n'est pas si simple là-bas.

Le modificateur statique devant une méthode ou un champ indique qu'il n'appartient pas à une instance de cette classe. Qu'est-ce que cela signifie pour nous? Lorsque nous avons décrit un champ ou une méthode de classe comme étant statique, il peut être appelé sans utiliser d'instance de la classe. C'est-à-dire qu'au lieu de cette construction : Cat cat = new Cat (); cat.method (), vous pouvez simplement écrire Cat.method (). A condition que la méthode soit déclarée statique. Les variables statiques sont les mêmes pour tous les objets de la classe. Ils ont un lien.

    Modificateurs de classe publique (

    static int otherStaticField = 5;

    public static void myStaticMethod () (

    unChamp = "Mon champ";

    // nonStaticField = ""; erreur de compilation

    // les champs non statiques ne peuvent pas être utilisés

    // dans les méthodes statiques

    public void myNonStaticMethod () (

    autreChampStatique = 4 ; // les champs statiques peuvent être utilisés

    // dans les méthodes non statiques

    // la méthode principale a également un modificateur statique

    nouveaux modificateurs () .myNonStaticMethod ();

    Modificateurs.myStaticMethod (); // appelle des méthodes et des champs statiques

    // via nomclasse.méthode

Une autre chose importante à noter à propos des modificateurs statiques est que les champs statiques sont initialisés au moment du chargement de la classe. Souvent dans divers types de tests Java, vous pouvez trouver le code suivant :

Question : qu'est-ce qui sera affiché sur la console ? Il ne faut pas oublier que le bloc statique sera affiché en premier dans tous les cas. Suivant sera le bloc par défaut. Ensuite, regardez l'écran de la console :

Le prochain modificateur que nous examinerons sera final.

Je pense que le mot final parle de lui-même. En appliquant le modificateur final, vous dites que les champs ne peuvent pas être modifiés, les méthodes sont remplacées et les classes ne peuvent pas être héritées (il y aura un article séparé sur l'héritage). Ce modificateur s'applique uniquement aux classes, méthodes et variables (également aux variables locales).

Nous parlerons du dernier modificateur des méthodes et des classes dans l'article de POO.

Ensuite, il y aura des modificateurs qui ne seront pas très clairs pour les débutants ou ceux qui liront cette série d'articles à partir de zéro. Et bien que je ne puisse toujours pas tout vous expliquer (du fait que vous ne connaissez pas le matériel d'accompagnement), je vous conseille tout de même de simplement vous familiariser avec eux. Lorsque viendra le temps d'utiliser ces modificateurs, vous comprendrez déjà la plupart des termes utilisés ci-dessous.

Modificateur synchronisé- indique que la méthode ne peut être utilisée que par un seul thread à la fois. Bien que cela ne vous dise rien, l'utilité de ce modificateur apparaîtra au fur et à mesure que nous découvrirons le multithreading.

Modificateur transitoire- indique que lors de la sérialisation de l'objet, certains champs doivent être ignorés. Généralement, ces champs stockent des valeurs intermédiaires.

Modificateur volatil- utilisé pour le multithreading. Lorsqu'un champ avec le modificateur volatile sera utilisé et modifié par plusieurs threads, ce modificateur garantit que le champ changera à son tour et qu'il n'y aura pas de confusion avec lui.

Modificateur originaire de avant que la déclaration de méthode indique que la méthode est écrite dans un autre langage de programmation. Généralement chez C.

Modificateur strictfp- Fournit des performances d'opérations sur des nombres de type float et double (à virgule flottante) selon la norme IEEE 754. Ou, plus simplement, garantit qu'au sein d'une méthode les résultats des calculs seront les mêmes sur toutes les plateformes.

je n'ai pas encore parlé du modificateur abstrait... Je vais vous en parler en quelques mots, car sans connaissance des bases de la programmation orientée objet, je ne vois pas l'intérêt d'en parler.

Une classe qui a le modificateur abstrait ne peut pas être instanciée. Son seul but est de s'étendre. Une classe abstraite peut contenir à la fois des méthodes abstraites et des méthodes ordinaires.

Nous parlerons plus en détail du modificateur abstrait dans l'article de POO.

Ceci conclut l'article sur les modificateurs. On n'a pas beaucoup parlé d'eux. Mais cela est dû au fait que nous n'avons pas encore de concepts POO. Dans quelques autres articles, nous développerons les modificateurs et remplirons les blancs.

Tout d'abord, examinons les modificateurs d'accès. Il n'y en a que quatre :

  • privé les membres de la classe ne sont accessibles qu'à l'intérieur de la classe
  • package-private ou par défaut (par défaut) les membres de la classe sont visibles à l'intérieur du package
  • protégé les membres de classe sont disponibles dans le package et dans les classes dérivées
  • Publique les membres de la classe sont disponibles pour tout le monde

Lors de l'héritage, il est possible de faire évoluer les modificateurs d'accès vers une PLUS GRANDE visibilité.

Le modificateur d'accès pour les constructeurs, les méthodes et les champs peut être n'importe lequel, mais avec les classes et leurs blocs, ce n'est pas si simple. Une classe ne peut être que publique ou par défaut, et il ne peut y avoir qu'une seule classe publique dans un fichier. Un bloc ne peut avoir qu'un seul modificateur - par défaut.

Modificateurs statiques, abstraits et finaux

Statique

  • S'applique aux classes internes, méthodes, variables et blocs logiques
  • Les variables statiques sont initialisées au moment du chargement de la classe
  • Les variables statiques sont les mêmes pour tous les objets de la classe (même référence)
  • Les méthodes statiques n'ont accès qu'aux variables statiques
  • Les méthodes et variables statiques sont accessibles via le nom de la classe
  • Les blocs statiques sont exécutés au moment du chargement de la classe
  • Les méthodes non statiques ne peuvent pas être remplacées en tant que statiques
  • Les variables locales ne peuvent pas être déclarées statiques
  • Les méthodes abstraites ne peuvent pas être statiques
  • Les champs statiques ne sont pas sérialisés (uniquement lors de l'implémentation de l'interface Serializable)
  • Seules les variables de classe statiques peuvent être passées au constructeur avec des paramètres, appelées via le mot super (// paramètre //) ou this (// paramètre //)

Résumé

  • S'applique uniquement aux méthodes et aux classes
  • Les méthodes abstraites n'ont pas de corps de méthode
  • C'est le contraire de final : une classe finale ne peut pas être héritée, une classe abstraite doit hériter
  • Une classe doit être déclarée abstraite si :
  1. il contient au moins une méthode abstraite
  2. il ne fournit pas une implémentation des méthodes abstraites héritées
  3. il ne fournit pas une implémentation des méthodes de l'interface dont il a déclaré l'implémentation
  4. il faut interdire la création d'instances de la classe

Final

  • Les champs ne peuvent pas être modifiés, les méthodes sont remplacées
  • Les classes ne peuvent pas être héritées
  • Ce modificateur s'applique uniquement aux classes, méthodes et variables (également aux variables locales)
  • Les arguments de méthode marqués comme finals sont en lecture seule, il y aura une erreur de compilation lors de la tentative de modification
  • Les variables finales ne sont pas initialisées par défaut, elles doivent être explicitement affectées d'une valeur lors de leur déclaration ou dans un constructeur, sinon - une erreur de compilation
  • Si la variable finale contient une référence à un objet, l'objet peut être modifié, mais la variable fera toujours référence au même objet
  • Cela est également vrai pour les tableaux, car les tableaux sont des objets, un tableau peut être modifié et une variable fera toujours référence au même tableau.
  • Si la classe est déclarée finale et abstraite (concepts mutuellement exclusifs), une erreur de compilation se produira
  • Puisqu'une classe finale ne peut pas être héritée, ses méthodes ne peuvent jamais être redéfinies.
Constructeur ne peut pas être statique, abstrait ou final

Les modificateurs strictfp, transitoire, volatile, synchronisé, natif

Strictfp

  • S'applique aux méthodes et aux classes
  • Fournit des opérations sur les nombres flottants et doubles (à virgule flottante) selon la norme IEEE 754

Transitoire

  • Applicable uniquement pour les variables de niveau classe (les variables locales ne peuvent pas être déclarées comme transitoires)
  • Les variables transitoires peuvent ne pas être finales ou statiques.
  • Les variables transitoires ne sont pas sérialisées

Volatil

  • Utilisé uniquement avec des variables
  • Peut être utilisé avec des variables statiques
  • Non utilisé avec les variables finales - La valeur d'une variable déclarée comme volatile modifiée par un thread est modifiée de manière asynchrone pour les autres threads
  • Utilisé dans les applications multithread

Synchronisé

  • S'applique uniquement aux méthodes ou aux parties de méthode
  • Utilisé pour contrôler l'accès à des parties importantes du code dans les programmes multithreads

Originaire de

  • Utilisé uniquement pour les méthodes
  • Indique que la méthode a été écrite dans un autre langage de programmation
  • Les classes en Java utilisent de nombreuses méthodes natives pour améliorer les performances et l'accès au matériel
  • Il est possible de passer/retourner des objets Java à partir de méthodes natives
  • La signature de la méthode doit se terminer par « ; », les accolades provoqueront une erreur de compilation

Fonctionnalités dans les interfaces

  • Les méthodes sont toujours publiques et abstraites, même si elles ne sont pas déclarées
  • Les méthodes ne peuvent pas être statiques, finales, strictfp, natives, privées, protégées
  • Les variables ne sont que finales statiques publiques, même si elles ne sont pas déclarées
  • Les variables ne peuvent pas être strictfp, natives, privées, protégées
  • Ne peut qu'hériter (étendre) d'une autre interface, pas implémenter une interface ou une classe (implémenter).

Regroupons tous les modificateurs :

Classer

Classe intérieure

Variable

Méthode

Constructeur

Bloc logique

Publique

Oui

Oui

Oui

Oui

Oui

Pas

protégé

Pas

Oui (sauf pour les cours locaux et anonymes)

Oui

Oui

Oui

Pas

défaut

Oui

Oui

Oui

Oui

Oui

privé

Pas

Oui (sauf pour les cours locaux et anonymes)

Oui

Oui

Oui

Pas

final

Oui

Oui (et pour une variable locale)

Oui

Pas

Pas

abstrait

Oui

Oui (sauf pour les cours anonymes)

Pas

Oui

Pas

Pas

statique

Pas

Oui (sauf pour les cours locaux et anonymes)

Oui

Oui

Pas

Oui

originaire de

Pas

Pas

Pas

Oui

Pas

Pas

transitoire

Pas

Pas

Oui

Pas

Pas

Pas

synchronisé

Pas

Pas

Pas

Oui

Pas

Oui (uniquement dans le cadre de la méthode)

volatil

Pas

Pas

Oui

Pas

Pas

Pas

strictfp

Oui

Oui

Pas

Oui

Pas

Pas

5

J'ai vu des discussions sur StackOverflow à ce sujet, mais je ne vois rien qui m'a aidé à comprendre le point suivant :

Je viens d'une formation en C++ et j'ai récemment commencé à apprendre Java. En C++, quand protégé, seule une sous-classe est utilisée pour accéder au membre (analogue à un champ en Java).

Il existe également des classes d'amis en C++ qui peuvent accéder aux caméras privées / protégées de la classe, ce qui donne de l'amitié. C'est un peu comme le modificateur de champ "package" en Java (le modificateur de champ par défaut), sauf qu'en C++, l'amitié donne accès à tous les membres privés, mais en Java, l'accès depuis les classes d'un package est spécifique à la classe domaine.

Ce que je ne peux pas comprendre, en supposant que je veuille uniquement donner accès aux sous-classes, c'est ce que je peux faire en C ++ en déclarant des membres protégés sur une classe qui ne "donne" pas d'amitiés.

Mais en Java, je ne sais pas comment faire cela, car à l'aide d'un modificateur de champ "protégé" - je donne également accès à toutes les classes du package. La seule façon que je trouve est de déclarer un champ protégé et d'isoler la classe dans son package.

De là, je conclus que le regroupement des classes en un seul package doit être effectué sur la base de "l'amitié" entre les classes. Est-ce vraiment le facteur principal lors du regroupement de packages ?

Une autre chose que je ne comprends pas, en Java, en supposant que j'ai deux champs dans la classe A : b, c. Je veux donner à B accès à b mais pas à, et je veux donner à C accès à c mais pas à b. et à "Paix" je veux que b, c se cachent. Comment puis je faire ça? Je suppose que B, C devrait être dans le même package que A. mais en déclarant b, c avec paquet avec le modificateur, je permets à B, C d'accéder à la fois à b et. Existe-t-il un moyen en Java de le faire?

J'espère avoir une explication à cette question

11

Une meilleure question, si elle est moins utile, sera plus étroite et plus spécifique. La question générale « tout sur la confidentialité en Java et C++ et en quoi ils diffèrent » est plus que trop large. Pouvez-vous poser une question plus précise sur un problème plus précis ? - Yakk 04 mars 15 2015-03-04 16:38:58

  • 4 réponses
  • Tri:

    Activité

2

En C++, lorsque la sécurité est utilisée, seule la sous-classe peut accéder à l'élément (analogue à un champ en Java).

Les spécificateurs d'accès sont également destinés aux fonctions/méthodes membres, pas seulement aux variables membres.

En C++ il y a aussi des classes "friends" qui peuvent accéder aux membres privés/protégés de la classe, ce qui donne "friendship". Celui-ci est un peu comme le modificateur de champ "package" en Java (le modificateur de champ par défaut), sauf qu'en C++, l'amitié donne accès à tous les membres privés, mais en Java, l'accès depuis les classes d'un même package est spécifique à le champ de classe.

Il n'y a pas que des classes d'amis, mais aussi des fonctions.

Il est vrai que l'accès aux parties privées Java est similaire, mais ce n'est pas un remplacement complet. Mieux vaut dire que ces deux fonctions ont sous-ensemble les problèmes qu'ils résolvent. Il y a des problèmes qui peuvent être résolus par un ami, mais pas par un forfait privé, et vice versa.

Ce que je n'ai pas pu comprendre, en supposant que je souhaite uniquement fournir un accès aux sous-classes, c'est ce que je peux faire en C ++ en déclarant les utilisateurs protégés dans une classe que l'amitié ne "donne pas".

Mais en Java, je ne sais pas comment je peux faire ça,

Réponse : Vous ne pouvez pas.

car à l'aide d'un modificateur de champ "protégé" - je donne également accès à toutes les classes du package.

La seule façon que je peux trouver est de déclarer un champ protégé et d'isoler la classe dans son package.

Techniquement, oui. Mais cela crée d'autres problèmes. Votre classe ne pourra plus accéder aux parties du package privé de son package précédent. Disons que votre BaseClass était à com.example.one. Vous allez le déplacer vers com.example.two. Désormais, il ne pourra plus accéder aux autres packages de classe privée com.example.one.

Est-ce vraiment le facteur principal lors du regroupement de packages ?

Oui, Java est conçu de cette façon. Vous pouvez essayer combattre les règles de la langue mais c'est une bataille perdue d'avance dans n'importe quel langage de programmation.

Une autre chose que je ne comprends pas en Java, en supposant que j'ai deux champs dans la classe A : b, c. Je veux donner à B accès à b mais pas à, et je veux donner à C accès à c mais pas à b. et dans "Monde", je veux que b, c se cachent. Comment puis je faire ça?

Cela ne peut pas être fait de manière propre (propre, je veux dire: sans aucun hack qui vous obligera à vérifier la pile d'appels au moment de l'exécution et à lever des exceptions).

Si vous êtes préoccupé par ce scénario parce que vous développez une API publique, une solution low-tech qui fonctionne généralement très bien consiste à créer un ou plusieurs packages * .internal et à documenter clairement le fait qu'ils ne doivent pas être utilisés dans le code client.

1

C'est tout un tas de questions ensemble...

Mais en Java, je ne sais pas comment je peux faire cela, car en utilisant un modificateur de champ "protégé", je donne également accès à toutes les classes du package.

En effet, il n'y a aucun moyen de donner accès uniquement aux sous-classes, mais pas aux classes d'un même package. C'était une décision de conception prise il y a des siècles...

La seule façon que je trouve est de déclarer un champ protégé et de l'isoler dans mon package.

C'est techniquement correct, même si cela sera de peu d'utilité. L'encapsulation de classe sert à regrouper des classes liées, où « frères et sœurs » signifie « des classes qui remplissent une relation particulière », c'est-à-dire qu'elles appartiennent au même cas d'utilisation, appartiennent au même niveau architectural, sont dans les mêmes entités, etc.

De là, je conclus que le regroupement des classes en un seul package doit être effectué sur la base de "l'amitié" entre les classes. Est-ce vraiment le facteur principal lors du regroupement de packages ?

Je crois avoir déjà répondu à cette question dans le paragraphe précédent : l'emballage sert à regrouper des classes apparentées selon des critères précis.

Pour vos classes A, B et C, par exemple avec des attributs :

Je pense que B, C devraient être tous les deux dans le même package, A déclarant b, avec le modificateur d'emballage, je laisse B, C accéder à la fois à b et k. Existe-t-il un moyen en Java de le faire?

La réponse est non, il n'y a pas de moyen simple et propre de le faire. Vous pourriez y parvenir avec quelques hacks ou des techniques plus avancées, mais encore une fois, cela faisait partie des décisions prises par les concepteurs de langage il y a longtemps ...

0

Réponse courte : il n'y a aucun moyen de le faire.

Si vous craignez une intrusion en injectant des clients de classe dans un package pour obtenir un accès non autorisé, vous pouvez déplacer le code sensible dans un package séparé et sceller le package dans un bocal auquel vous le livrez : http://docs.oracle. com/javase/tutorial /deployment/jar/sealman.html

1

Il est implicitement supposé que toutes les classes d'un package se "connaissent" (car elles ont été écrites par la même personne / entreprise / organisation). De cette façon, soit ils n'ont pas accès aux champs protégés, soit s'ils le font, ils savent comment le faire correctement.

Les classes du même package sont supposées être plus liées les unes aux autres que le parent ne l'est à la classe dérivée, car la classe dérivée peut en fait être écrite par quelqu'un d'autre. Ils ont donc décidé que la protection privée était plus limitée que protégée.

Donc, je suppose que vous n'avez pas à vous soucier de la façon dont les classes d'un même package peuvent accéder aux champs des autres. En général, je n'utilise tout simplement pas cette fonction, sauf lorsque j'écris des itérateurs.

Si vous avez deux champs, vous pouvez en faire des classes internes afin qu'ils aient accès à des champs privés (encore une fois, logique : si une classe est à l'intérieur d'une autre classe, elle connaît la sémantique de cette classe) et peut fournir cet accès à leurs dérivés classes via des méthodes protégées.

Vous pouvez bien sûr proposer un protocole d'échange de jetons complexe pour rendre ce champ accessible uniquement aux instances B / C, mais ce serait une surcharge formidable et un autre objet peut toujours utiliser la réflexion pour accéder à tous les membres privés si vous ne le désactivez pas en utilisant des politiques de sécurité, ce qui n'est généralement pas le cas, mais encore une fois, les politiques de sécurité sont finalement décidées par le propriétaire de la JVM.

Donc, en fin de compte, la meilleure façon de faire ce que vous dites en Java est soit de les mettre dans le même package, soit d'écrire B et C en tant que classes internes de A afin qu'ils puissent accéder directement aux membres privés de A et les exposer aux classes dérivées .

Classe publique A (classe abstraite statique publique B (protégée Quel que soit getWhatever (A a) (retour ab;) protected void setWhatever (A a, Quelle que soit la valeur) (ab = valeur;)) Classe abstraite statique publique C (protégée Quel que soit getWhatever (A a) (retour ac;) protected void setWhatever (A a, Quelle que soit la valeur) (ac = valeur;)) private Quelle que soit b; private Quelle que soit c;)

encore une fois, vous pensez toujours que les classes dans le même package ne feront jamais rien de mal.

Dernière mise à jour : 03.10.2019

Tous les membres d'une classe - champs, méthodes, propriétés - ils ont tous modificateurs d'accès... Les modificateurs d'accès vous permettent de définir une portée valide pour les membres de la classe. C'est-à-dire que les modificateurs d'accès définissent le contexte dans lequel une variable ou une méthode donnée peut être utilisée. Dans les rubriques précédentes, nous l'avons déjà rencontré lorsque nous avons déclaré des champs de classe publics (c'est-à-dire avec le modificateur public).

Les modificateurs d'accès suivants sont utilisés en C# :

    public : public, classe publique ou membre d'une classe. Un tel membre de classe est accessible de n'importe où dans le code, ainsi qu'à partir d'autres programmes et assemblys.

    private : une classe privée ou un membre d'une classe. Représente l'exact opposé du modificateur public. Une telle classe privée ou membre de classe n'est accessible qu'à partir du code de la même classe ou du même contexte.

    protected : un tel membre de classe est accessible de n'importe où dans la classe actuelle ou dans les classes dérivées. Cependant, les classes dérivées peuvent être situées dans d'autres assemblys.

    interne : une classe et les membres d'une classe avec un modificateur similaire sont accessibles de n'importe où dans le code dans le même assembly, mais il n'est pas disponible pour d'autres programmes et assemblys (comme c'est le cas avec le modificateur public).

    interne protégé : combine la fonctionnalité de deux modificateurs. Les classes et les membres de classe avec ce modificateur sont disponibles à partir de l'assembly actuel et des classes dérivées.

    private protected : un tel membre de classe est accessible depuis n'importe où dans la classe actuelle ou dans les classes dérivées définies dans le même assembly.

Nous pouvons définir explicitement le modificateur d'accès, par exemple :

État de la classe privée protégée (int a; protected void Print () (Console.WriteLine ($ "a = (a)");))

Ou nous pouvons ignorer la spécification :

État de la classe (int a; void Print () (Console.WriteLine ($ "a = (a)");))

Si aucun modificateur d'accès n'est défini pour les champs et les méthodes, le modificateur private est utilisé pour eux par défaut.

Les classes et structures déclarées sans modificateur ont un accès interne par défaut.

Toutes les classes et structures qui sont directement définies dans des espaces de noms qui ne sont pas imbriquées dans d'autres classes ne peuvent avoir que des modificateurs publics ou internes.

Regardons un exemple et créons la classe State suivante :

Public class State (// est identique à private int defaultVar ; int defaultVar ; // le champ n'est accessible qu'à partir de la classe actuelle private int privateVar ; // accessible à partir de la classe actuelle et des classes dérivées définies dans le même projet protected private int protectedPrivateVar; // disponible à partir de la classe actuelle et des classes dérivées protected int protectedVar; // disponible n'importe où dans le projet en cours internal int internalVar; // disponible n'importe où dans le projet en cours et à partir des classes héritées d'autres projets protected internal int protectedInternalVar; // disponible n'importe où dans le programme, ainsi que pour d'autres programmes et assemblys public int publicVar; // a par défaut un modificateur private void defaultMethod() => Console.WriteLine ($ "defaultVar = (defaultVar)"); / / la méthode est accessible uniquement depuis la classe courante private void privateMethod() => Console.WriteLine ($ "privateVar = (privateVar)"); // accessible depuis la classe courante et les classes dérivées qui sont définies dans le même paragraphe protected private void protectedPrivateMethod () => Console.WriteLine ($ "protectedPrivateVar = (protectedPrivateVar)"); // accessible depuis la classe courante et les classes dérivées protected void protectedMethod () => Console.WriteLine ($ "protectedVar = (protectedVar)"); // disponible n'importe où dans le projet en cours internal void internalMethod () => Console.WriteLine ($ "internalVar = (internalVar)"); // disponible n'importe où dans le projet en cours et à partir des classes héritées dans d'autres projets protected internal void protectedInternalMethod () => Console.WriteLine ($ "protectedInternalVar = (protectedInternalVar)"); // disponible n'importe où dans le programme, ainsi que pour d'autres programmes et assemblys public void publicMethod () => Console.WriteLine ($ "publicVar = (publicVar)"); )

Étant donné que la classe State est déclarée avec le modificateur public, elle sera accessible de n'importe où dans le programme, ainsi que d'autres programmes et assemblys. La classe State a cinq champs pour chaque niveau d'accès. Plus une variable sans modificateur, qui est privée par défaut.

Il existe également six méthodes qui afficheront les valeurs des champs de classe à l'écran. Veuillez noter que puisque tous les modificateurs vous permettent d'utiliser des membres de classe à l'intérieur de cette classe, toutes les variables de classe, y compris les variables privées, sont disponibles pour toutes ses méthodes, car elles sont toutes dans le contexte de la classe State.

Voyons maintenant comment nous pouvons utiliser les variables de notre classe dans le programme (c'est-à-dire dans la méthode Main de la classe Program), si les classes State et Program sont dans le même projet :

Class Program (static void Main (string args) (State state1 = new State (); // nous ne pourrons pas affecter la valeur à la variable defaultVar, // car elle a un modificateur privé et la classe Program ne voit pas it // Et l'environnement soulignera comme étant incorrect state1.defaultVar = 5; // Erreur, vous ne pouvez pas accéder // La même chose s'applique à la variable privateVar state1.privateVar = 5; // Erreur, vous ne pouvez pas accéder // assigner la valeur de la variable protectedPrivateVar ne fonctionnera pas, // puisque la classe Program n'est pas une sous-classe de la classe State state1.protectedPrivateVar = 5; // Erreur, vous ne pouvez pas y accéder // attribuer la valeur de la variable protectedVar échouera également , // puisque la classe Program n'est pas une sous-classe de la classe State state1.protectedVar = 5 ; // Erreur, vous ne pouvez pas accéder // la variable internalVar avec le modificateur interne est accessible de n'importe où dans le projet en cours // donc, attribuez-lui en toute sécurité la valeur state1.internalVar = 5 ; // la variable protectedInternalVar est également accessible de n'importe où dans le projet actuel state1.protectedInternalVar = 5; // publicVar est publiquement disponible state1.publicVar = 5; ))

Ainsi, nous n'avons pu définir que les variables internalVar, protectedInternalVar et publicVar, car leurs modificateurs nous permettent de les utiliser dans ce contexte.

La situation est similaire avec les méthodes :

Programme de classe (static void Main (string args) (State state1 = new State (); state1.defaultMethod (); // Erreur, n'est pas accessible state1.privateMethod (); // Erreur, n'est pas accessible state1.protectedPrivateMethod () ; // Erreur, vous ne pouvez pas obtenir l'accès state1.protectedMethod (); // Erreur, vous ne pouvez pas obtenir l'accès state1.internalMethod (); // normes state1.protectedInternalMethod (); // normes state1.publicMethod (); // normes ))

Ici, seules trois méthodes étaient disponibles : internalMethod, protectedInternalMethod, publicMethod, qui ont respectivement les modificateurs internal, protected internal et public.

Grâce à un tel système de modificateurs d'accès, il est possible de masquer certains aspects de l'implémentation de la classe aux autres parties du programme.

Malgré le fait que les modificateurs publics et internes soient similaires dans leur action, ils ont une grande différence. Les classes et les membres d'une classe avec le modificateur public seront également disponibles pour d'autres programmes si la classe donnée est placée dans une dll de bibliothèque dynamique puis utilisée dans ces programmes.



Vous avez aimé l'article ? Partagez-le