certification java

OCPJP 6 – Jour 3 – Classe Java : Membres et visibilité

Dans le chapitre précédent nous avons vu la notion de visibilité sur une classe, nous allons voir maintenant cette notion sur les données membres d’une classe, à savoir les méthodes et les attributs.

Il est important de garder à l’esprit que si une classe A ne peut être accédée par une classe B, alors aucun membre de cette classe A ne sera accessible par la classe B (même si un membre est déclaré comme public). Vérifier la visibilité d’une classe est la première chose à faire car vérifier la visibilité d’un membre d’une classe n’a de sens que si cette classe est visible.

3.1 – Les modificateurs d’accès

En Java, les membres d’une classe peuvent avoir 4 niveaux de visibilité :

  • public
  • protected
  • default (absence de modificateur)
  • private

Selon leur niveau de visibilité, les attributs et les méthodes peuvent être accessibles ou non depuis des classes du même package ou depuis des classes d’autres packages. Si on tente de compiler une classe invoquant une méthode ou un attribut non accessible, le compilateur génère une erreur pour indiquer que l’entité en question n’est pas accessible.

Dans ce chapitre nous verrons 3 modes d’accès pour chaque niveau de visibilité :

  • accès à un membre dans sa propre classe
  • accès à un membre dans une autre classe via une référence
  • accès à un membre par héritage

Public

Un membre déclaré public est accessible partout, indépendamment du package (si évidemment la classe de ce membre est visible).

Exemple 1 :

Dans cet exemple, Plane et Seaplane sont dans deux packages différents. Seaplane peut tout de même accéder à la méthode increaseThrottle de la classe Plane car cette méthode et cette classe sont déclarées public.

Exemple 2 :

Dans le cas d’une classe dérivée (ou classe fille), si un membre de sa classe mère est déclarée public, cette classe fille hérite de ce membre, quelque soit le package auquel ces deux classes appartiennent.
visibilité

Private

Un membre déclaré private n’est accessible que dans la classe où celui-ci est défini.

Modifions le code précédent :

La méthode increaseThrottle() est désormais déclarée private. Aucune autre classe peut y accéder.

Si nous essayons de compiler la classe Seaplane, le compilateur générera l’erreur suivante :

De même une classe fille située dans un même package ne pourra accéder à un membre de sa classe mère :

Le compilateur générera l’erreur suivante :

Une méthode private ne peut être surchargée par une classe fille.
visibilité

Default

Un membre déclaré default (sans modificateur) est accessible dans la classe où celui-ci est défini et dans les classes faisant partie du même package. En d’autres termes, un membre déclaré default est restreint à son propre package. Penser default, c’est penser package.

Exemple 1 :

Ces deux classes appartiennent au même package et vont compiler correctement.

Exemple 2 :

Dans cet exemple la classe fille Apache (appartenant à un package différent de sa classe mère) ne pourra accéder à l’attribut altitude de sa classe mère. Le compilateur générera l’erreur suivante :

Protected

Un membre déclaré protected est accessible dans la classe où celui-ci est défini, dans toutes les classes faisant partie du même package et uniquement par héritage dans les sous-classes d’un package différent. Penser protected, c’est penser package + enfants.

Exemple dans un même package…


Exemple 1 :

Comme le niveau d’accès default, l’attribut altitude est accessible dans toutes les classes d’un même package.

Exemples dans des packages différents…


Exemple 2 :

Dans cet exemple, la classe Plane et sous-classe Glider sont dans deux packages différents. L’attribut altitude est tout de même accessible au sein de la sous-classe par héritage.

Ajoutons maintenant une 3ème classe Paraglider, sous-classe de Glider qui elle-même est une sous-classe de Plane. Le membre altitude de la classe Plane sera accessible au sein de la classe Paraglider.

Exemple 3 :

En résumé, un membre protected est accessible dans toutes les sous-classes (quelque soit le niveau) d’une classe où est déclaré le membre protected.

Cependant, accéder à un membre protégé de la classe mère via une instance de celle-ci n’est pas autorisé :

Exemple 4 :

Imaginons un dernier cas où la classe Plane et Glider seraient toujours dans des packages différents et cette classe Glider hériterait de l’attribut altitude de la classe Plane par héritage. Ajoutons à cela une 3ème classe Paraglider appartenant au même package que la classe Glider. L’attribut altitude sera-t-il accessible au sein de la classe Paraglider via une instance de la classe Glider ?

Exemple 5 :

La réponse est non. Une fois que la sous-classe hérite d’un membre protected, ce membre reste inaccessible via une référence de cette sous-classe.

Tableau récapitulatif

publicProtectedDefaultPrivate
Classe
Package
Sous-classe (même package)
Sous-classe (package différent) (héritage)
World

Informations complémentaires

Les modificateurs de visibilité ne peuvent être appliqués à des variables locales. Ce code est donc incorrect :

3.2 – Les modificateurs spéciaux

Final

…associé à une méthode

Ajouté devant une méthode, le mot-clé final indique que cette méthode ne peut être redéfinie dans une classe fille.

Pour information, on parle de redéfinition et non de surcharge. Pour rappel la surcharge consiste à créer une méthode du même nom mais avec des paramètres différents et la redéfinition consiste à créer une méthode de remplacement dans une classe fille, avec la même signature (paramètre et type de retour) que la méthode de la classe parente qu’elle remplace.
Tout comme la classe String, certaines méthodes ne peuvent être redéfinies pour des raisons de sécurité et ainsi forcer l’utilisation des méthodes de la classe mère.

Exemple :

Le compilateur générera l’erreur suivante :

Dans l’exemple précédent, il est tout à fait possible de dériver la classe Glider car cette classe ne possède pas le modificateur final. Cependant, la méthode getType(), possédant le mot-clé final, ne peut être redéfinie dans la sous-classe Paraglider.

…associé à un attribut

Ajouté devant un attribut, le mot-clé final rend l’attribut immuable, dès lors qu’il est initialisé (autrement dit, il n’est pas obligatoire de l’initialiser dès la déclaration, contrairement à d’autres langages).

  • Appliqué à un attribut de type primitif, ce dernier devient une constante.
    Exemple :
  • Appliqué à un objet le modificateur final fige la référence (dans ce cas, la référence devient une constante), et non la valeur de la référence. Ainsi il est toujours possible de modifier les valeurs de l’objet. Cependant, une fois la référence liée à un objet, elle ne peut jamais changer pour pointer vers un autre objet. Quoi qu’il en soit, l’objet lui-même peut être modifié. Cette règle s’applique aussi aux tableaux.
    Exemple :

Synchronized

Le modificateur synchronized indique qu’une méthode ne peut être accédée que par un seul thread à la fois.

Nous détaillerons ce modificateur dans un chapitre suivant. Il faut simplement savoir que celui-ci peut être associé aux quatre modificateurs d’accès et ne peut être appliqué qu’aux méthodes.

Native

Le modificateur native indique qu’une méthode est implémentée dans une bibliothèque native, souvent écrite en C.

Nous ne détaillerons pas ce modificateur mais il faut simplement savoir que celui-ci peut être associé aux quatre modificateurs d’accès et ne peut être appliqué qu’aux méthodes. Celles-ci sont, d’un point de vue syntaxique, identiques aux méthodes abstraites, elles ne sont pas implémentées et se terminent par un point-virgule.

Strictfp

Le modificateur strictfp (abréviation de Strict floating point) force la JVM à évaluer les opérations à virgules flottantes (sur les double et float) conformément à la spécification Java, c’est-à-dire de la gauche vers la droite.

Un processeur de virgule flottante peut effectuer des calculs avec plus de précision et une plus grande plage de valeurs que ce que requiert la spécification Java. Le mot-clé strictfp peut être utilisé avec des classes ou des méthodes afin de spécifier la conformité avec la spécification Java (IEEE-754) et ainsi obtenir des résultats flottants identiques d’un environnement à l’autre. Si ce mot clé n’est pas défini, les calculs à virgule flottante peuvent varier d’un environnement à l’autre.

Ce modificateur peut seulement s’appliquer aux classes et aux méthodes mais jamais aux constructeurs ni aux variables.


Auteur
AuteurEdouard WATTECAMPS

0 réponses

Répondre

Se joindre à la discussion ?
Vous êtes libre de contribuer !

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *