• 15 heures
  • Facile

Ce cours est visible gratuitement en ligne.

course.header.alt.is_video

course.header.alt.is_certifying

J'ai tout compris !

Mis à jour le 19/05/2021

Saisissez la portée de vos variables dans votre code

Connectez-vous ou inscrivez-vous gratuitement pour bénéficier de toutes les fonctionnalités de ce cours !

Dans ce chapitre, nous allons nous rendre compte que chaque variable déclarée en Java a une portée. C'est-à-dire un champ d’accessibilité dans lequel elle peut être utilisée.

Déterminez la portée de la variable

Chaque variable n'est disponible (et accessible) que dans le contexte dans lequel elle a été déclarée. Pour déterminer le contexte, reportez-vous aux marques d'ouverture et de fermeture les plus proches qui entourent la déclaration. La plupart des langages de programmation utilisent des accolades ouvrantes et fermantes ({}) pour marquer le début et la fin d'un bloc de code. Jetez un œil à cet exemple :

Portée d’une variable
Portée d’une variable

Il n'est pas nécessaire de comprendre chaque morceau de code ici. Il vous suffit de vous concentrer sur les accolades ouvrantes et fermantes. 🙂 Quand nous parlons de la disponibilité d'une variable dans un contexte, nous faisons référence à la portée (scope). Ici, vous pouvez voir que la variable  root  a été déclarée entre les deux accolades (ouvrante et fermante) entourées en violet. La portée de cette variable est tout ce qui se trouve entre ces deux accolades.

La portée d'une variable peut être locale ou globale, en fonction de l'endroit où la variable est déclarée. Une variable globale peut être disponible pour toutes les classes et méthodes d'un programme, alors qu'une variable locale ne peut être disponible que dans la méthode dans laquelle elle est déclarée :

Portée local ou global
Portée locale ou globale

Ici, nous avons un peu élargi le code et étendu notre premier bloc de code pour en inclure un autre ! Si vous tracez les lignes violettes, vous pouvez voir que les parenthèses du premier bloc englobent tout le code du second. Ensuite, vous pouvez voir qu'une nouvelle variable,  spy, a été déclarée dans le cadre local vert.

Puisque la variable  root  a été déclarée dans la portée globale, cela signifie qu'elle est accessible à tout ce qui est entre parenthèses violettes, y compris tout ce qui est déclaré dans la portée locale. Dans le deuxième bloc de code, vous pouvez voir une ligne juste en dessous de la déclaration de la variable «  spy  » qui utilise  root. Cela est autorisé !

Cependant, tout ce qui est dans la portée locale n'est pas disponible pour la portée globale, ni aucun autre bloc de code local. Prenons un autre exemple :

Portées multiples
Portées multiples

Ici nous avons ajouté un autre bloc de code, qui a sa propre portée locale et sa propre variable,  anotherSpy. Maintenant, regardez la dernière ligne de notre bloc variable «spy » :

System.out.println(anotherSpy); // Erreur

On dirait qu'il y a une erreur ! C'est parce qu'elle essaie d'utiliser la variable  anotherSpy. Mais ce n'est pas possible car  anotherSpy  n'est ni dans la portée globale ni dans la même portée locale. Cela signifie que ce bloc de code ne peut pas y accéder.  anotherSpy  est disponible uniquement dans le bloc de code dans lequel il a été déclaré.

L'inverse est également vrai. Vous voyez que la dernière ligne de notre dernier bloc de code possède elle aussi une erreur :

System.out.println(spy); // Erreur

Ici, le code essaie d'utiliser la variable  spy  d'un autre bloc de code. Mais ce n'est pas possible car  spy  n'est pas dans la même portée que le bloc de code qui essaie de l'utiliser.

Portée variable dans les classes

Lorsque vous déclarez une classe, les mêmes règles générales concernant la portée s'appliquent : chaque variable n'est accessible qu'au sein de son bloc de déclaration. Expérimentons avec une classe  Unicorn  :

La classe Unicorn
La classe Unicorn

Tout comme dans notre premier exemple, il y a des variables de classe globale ainsi que des variables locales. Revoyons cela plus en détail :

  • les variables  height  et  power  sont des champs de la classe et sont accessibles partout dans la classe ;

  • la variable  minutesToSleep  n'est accessible que dans le cadre local du bloc de code dans lequel elle est déclarée ;

  • la variable  minutesToRun  n'est accessible que dans le cadre local du bloc de code dans lequel elle est déclarée.

La portée d'une variable limite (par définition) son accessibilité. Cependant, les champs de classe sont accessibles en dehors de la classe et peuvent être utilisés par tout autre bloc de code.

Dans notre exemple, ce sont les champs  height  et  power. Si nous déclarons une variable Unicorn (licorne), nous pouvons lire ou modifier ces valeurs :

Unicorn firefly = new Unicorn();
System.out.println("I know it's height: "+(unicorn.height);
// et peut changer son pouvoir !
unicorn.power = 0; // pas drôle!

Le fait d'être capable de jouer avec les variables de classe peut avoir des conséquences graves. La bonne nouvelle, c'est que vous pouvez le contrôler ! Avant de vérifier comment, assurez-vous de vous exercer à la détermination de la portée des variables.

Contrôle d'accès

Nous allons utiliser cette idée de contrôle d'accès en implémentant un accès restreint à une classe, un module ou un fichier. Vous savez déjà ce que sont une classe et un fichier depuis que nous travaillons avec eux !

D'ailleurs, un fichier de code est aussi appelé un fichier source.

Un module est un ensemble de fichiers sources associés à un nom, comme un framework. Un framework est un ensemble de fonctionnalités regroupées par contexte particulier. Ceci permet d'accélérer le processus de développement en donnant des conseils sur la façon d'écrire le code.

Chaque environnement de développement fournit un certain nombre de frameworks. Le fait est que la mise en œuvre de ces frameworks dépasse de loin ce que les développeurs qui les utilisent peuvent voir et utiliser. Cela se fait en limitant l'accès aux détails de l'implémentation, également connue sous le nom d'implémentation du contrôle d'accès.

Niveaux de contrôle

En Java, vous devez utiliser un des mots clés pour désigner un niveau de contrôle :

  • public : visible pour tous et par conséquent le moins restrictif ;

  • protected (protégé) : visible pour le package et l'ensemble de ses sous-classes ;

  • package-protected (protégé par paquet) : généralement visible uniquement par le package dans lequel il se trouve (paramètres par défaut) ;

  • private (privé) : accessible uniquement dans le contexte dans lequel les variables sont définies (à l'intérieur de la classe dans laquelle il est situé).

La mise en place de ces restrictions distinctes facilite grandement le développement. Vous n'avez pas à vous soucier de la visibilité non désirée de votre implémentation et plus encore, des modifications non désirées.

Placez un mot clé approprié devant la déclaration correspondante :

class Unicorn {
// propriétés
private int height = 170;
public String power = "Double.infinity";
// méthodes
private static void sleep() {
}
public static void run() {
}
}

Ensuite, si vous essayez d'accéder à des membres privés de l'extérieur de la classe, vous obtenez des erreurs :

Unicorn unicorn = new Unicorn();
System.out.println(unicorn.power); // Ok
unicorn.height = 180; // Erreur
unicorn.sleep(); // Erreur
unicorn.run(); // Ok

Les niveaux de contrôle peuvent être affectés aux éléments de classe ainsi qu'aux classes :

public class PublicClass {
}
private class PrivateClass {
}

En plus de la sécurité, la spécification de niveaux de contrôle pour les membres du groupe permet une meilleure lisibilité. Si un développeur prépare un fichier source, les éléments pouvant être utilisés en externe seront ainsi toujours visibles.

Hiérarchie de contrôle

Un élément peut avoir le même niveau de contrôle ou un niveau de contrôle plus restrictif que son élément contenant :

public class PublicClass {
public boolean publicProperty = true;
int internalProperty = 0; //par défaut pour package-private
private String fileprivateProperty = "Hello!"
private static void privateMethod() {
}
}

Dans l'exemple ci-dessus, la classe est déclarée  public. Puisque la classe est l'élément contenant, cela signifie que tous les éléments de cette classe peuvent être du même niveau d'exposition d'un niveau inférieur. Dans ce cas, cela comprend tous les niveaux.

Si vous déclarez une classe comme  private, ses éléments ne peuvent être que  package-private  ou  private  :

class PrivateClass {
int internalProperty = 0; // assigne automatiquement package-private par défaut
protected defaultProperty = true; // assigne automatiquement package-private
public boolean publicProperty = true; // convertit automatiquement en package-private
private String fileprivateProperty = "Hello!"; //disponible seulement pour la classe
private static void privateMethod() {
}
}

Dans l'exemple ci-dessus, nous avons ajouté un attribut sans mot clé de contrôle d'accès explicite. Dans ce scénario, il assume par défaut le niveau de l'élément contenant. Dans ce cas, c'est notre classe, donc il assume le niveau de  PrivateClass.

Une classe de premier niveau ne peut pas être marquée comme private, mais la définir comme « par défaut » la placera dans le niveau package-protected. Lors de la déclaration d'une variable d'une classe, si le niveau de contrôle du contexte de déclaration est supérieur à celui de la classe, la variable doit également avoir un niveau de contrôle explicite. Déclarons une variable PrivateClass :

PrivateClass a = new PrivateClass(); // Erreur
private PrivateClass b = new PrivateClass(); // Ok
private PrivateClass c = new PrivateClass(); // Ok

Comme vous pouvez le voir, si le niveau d'accès par défaut du contexte d'une variable est supérieur à une classe que vous lui affectez, vous devez explicitement spécifier le niveau de la variable comme étant le même ou inférieur à celui de la classe.

En résumé

Dans ce chapitre, vous avez appris ce qu'est l'accessibilité d'une variable :

  1. Une portée (scope) d'une variable est la zone de code où elle a été déclarée.

  2. La portée variable générale s'applique à tous les blocs de code, y compris les classes.

Un autre moyen nécessaire pour contrôler l'accès aux variables et aux fonctions est d'utiliser des niveaux de contrôle : public, protected, package-protected et private.

Nous verrons dans le prochain chapitre l'écriture des boucles de traitement en Java.

Exemple de certificat de réussite
Exemple de certificat de réussite