Dans cette partie, après avoir fait quelques programmes, nous allons voir ou revoir les règles essentielles du développement Java.
packageUn package permet de regrouper des classes qui partagent un même objectif dans une application ou une librairie.
Par exemple, les classes du package java.net regroupent des outils d’accès au réseau. Les classes du package java.io regroupent les classes de gestion de flux d’entrées/sorties.
Les packages:
Les noms des paquetages sont TOUJOURS en minuscules (aucune majuscule).
Vérifiez à quelles packages appartiennent les classes String, Object et List.
Concernant la classe List, déterminez si elle est unique (dans l’ensemble des classes de l’API Java SE).
Une classe est un modèle. Elle permet de déterminer le comportement d’un ensemble d’objets similaires et leurs caractéristiques et comportements.
La classe va servir de prototype pour créer une instance. L’instance (ou exemplaire) d’une classe se comportera comme définit dans ce modèle.
L’instantiation se fait avec le mot clef new
L’identification d’une classe se fait à partir de son nom et de son paquetage.
Ainsi, le nom complet de la classe String est java.lang.String.
Le nom complet de la classe Date est java.util.Date ou java.sql.Date. En effet il y a plusieurs classes Date.
Si on veut les différencier il faut utiliser le nom complet. Ce qui serait peu lisible en pratique. Comme dans une classe on n’utilise en général qu’une de ces deux classes, on va utiliser un import.
Ainsi, au lieu de devoir écrire:
On va écrire:
Une fois un import fait dans un fichier, il est valide pour tout le fichier.
Il est possible aussi d’importer toutes les classes d’un même paquet en une seule fois avec le joker *.
Les attributs d’une classe sont les éléments contenus par une classe.
Dans l’exemple précédent, l’attribut nom permet de stocker le nom du RendezVous sous forme d’une chaîne de caractère.
La valeur d’un attribut est propre à une instance de classe. Chaque exemplaire d’une classe conservera une valeur spécifique pour cet attribut.
Testez le code suivant (à mettre dans une méthode main):
RendezVous rendezVousA = new RendezVous();
rendezVousA.nom = "Premier rendez-vous";
RendezVous rendezVousB = new RendezVous();
rendezVousB.nom = "Second rendez-vous";
System.out.println(rendezVousA); //RendezVous A
System.out.println(rendezVousB); //RendezVous BIl est possible de définir des attributs communs à toutes les instances d’une classe. Ce sont les attributs de classe.
Ils sont définis en utilisant le mot clé static.
class RendezVous{
String nom;
static int compteur;
}
...
RendezVous rendezVousA = new RendezVous();
rendezVousA.compteur = 1;
RendezVous rendezVousB = new RendezVous();
rendezVousB.compteur += 1;
System.out.println(rendezVousA.compteur); //2
System.out.println(rendezVousB.compteur); //2Remarques importantes
Au lieu d’écrire:
Ecrire:
Une méthode permet de définir un comportement, d’implémenter un algorithme.
Elles sont de deux types:
Déclaration
Utilisation
Déclaration
class RendezVous{
static int compteur = 0;
RendezVous(){
compteur++;
}
static int getNombreDInstances(){
return compteur;
}
}Utilisation
Nous allons tester les attributs de classe.
Pour cela, implémentez la classe Forme ci-dessus.
Ajoutez une méthode dont la signature est la suivante:
public static String getInformationNombreFormes()Cette méthode renvoie une chaîne de caractères de la forme suivante:
"Le nombre de formes instanciées est 3"
Où 3 est à remplacer par le compteur de formes.
Ensuite, créer une classe principale GenereForme qui contiendra le code suivant:
Forme f ;
f = new Forme();
f = new Forme();
System.out.println(f.getInformationNombreFormes());
f = new Forme();
f = new Forme();
System.out.println(f.getInformationNombreFormes());Que dire de la variable f qui est ici utilisée ?
En lançant ce programme, que constatez-vous ?
Diagramme de classe

Normalement pour utiliser un membre d’une classe, il faut l’écrire explicitement:
Les static import permettent d’utiliser directement depuis une autre classe des membres statiques d’une classe particulière.
import static java.lang.Math.PI;
import static java.lang.Math.cos;
...
double rayon = cos(beta * PI);ATTENTION
Ceci est à utiliser avec précaution et parcimonie !
Il est facile de se retrouver avec des membres avec le même nom que ceux importés d’une autre classe.
Les constantes sont des attributs qui ne peuvent plus changer de valeur.
Pour les définir on utilise le mot clé final
En fait, tout membre d’une classe ayant un attribut final ne pourra plus être modifié ou surchargé.
Ainsi une méthode déclarée final ne pourra pas être surchargée par une classe qui hériterait de la classe courante.
class Polygone{
String nom ;
final int JE_NE_PEUX_PAS_CHANGER = 0;
final String getNom(){
return nom;
}
void changer(){
JE_NE_PEUX_PAS_CHANGER = 1 ; //ERREUR DE COMPILATION
}
}
class Triangle extends Polygone{
String getNom(){ // ERREUR de COMPILATION
return "Triangle."+nom;
}
}
C’est un ensemble de règles qui permettent d’écrire un code dans une manière lisible et compréhensible par un maximum de développeurs.
Ces règles évoluent d’un langage à l’autre. En Java, elles sont essentielles car elles permettent, d’un seul coup d’oeil, de déterminer si on a affaire à une classe/un type, une variable/attribut/paramètre ou une constante.
Elles sont là pour améliorer la compréhension des éléments du code et faire en sorte qu’il soit “auto-commenté” le plus possible. C’est à dire que l’on va utiliser des noms qui soient parlant, que ce soit pour les méthodes, attributs, variables ou classes.
Un lien vers les conventions de codage telles que définies aux origines du langage Java.
http://www.oracle.com/technetwork/java/codeconventions-150003.pdf
Autre lien avec quelques exemples:
https://en.wikibooks.org/wiki/Java_Programming/Coding_conventions pour compléter vos connaissances.
Les mots qu’il est interdit d’utiliser pour nommer une attribut, une méthode, une variable, un paramètre, une classe, etc, sont donnés à l’adresse suivante:
https://docs.oracle.com/javase/tutorial/java/nutsandbolts/_keywords.html
Tous les composants d’un programme Java doivent être nommés.
Ces noms sont donnés:
Ces noms sont appelés des identifiants. Leur nom est sensible à la casse (différence majuscule/minuscule).
Les règles pour définir un identifiant sont les suivantes:
a à z ou A à Z),$,_;Exemples d’identifiants autorisés:
age$distance_valeur__1_dataExemples d’identifiants incorrects:
12singes-salaireEn Java on utilise la notation CamelCase (casse en dos de chameau).
Pour nommer un attribut, une méthode ou une classe, on l’écrit sous la forme de mots accolés, avec la première lettre du mot qui commence par une majuscule.
La première lettre du premier mot est:
Exemple:
class FormeSpeciale {
String leNomDeCetteForme ;
static final int CODE_FORME = 3;
String getLeNomDeCetteForme(){
return leNomDeCetteForme;
}
void setLeNomDeCetteForme(String nouveauNom){
leNomDeCetteForme = nouveauNom;
}Pour les constantes on utilise une règle différente: majuscules avec des mots séparés par des tirets-bas (underscore).
Les classes, attributs ou méthodes peuvent être accessibles (on dit aussi visibles) ou non à l’intérieur d’autres classes, qu’elles soient du même package ou pas.
Pour indiquer les degrés d’accessibilités on utilise des modificateurs d’accessibilité (access modifiers).
On utilise pour cela ces trois mots clés:
privateprotectedpublic| Modificateur | Applicable à | Signification |
|---|---|---|
public |
classe | est visible partout |
public |
membre (méthode ou attribut) | visible partout où sa classe est visible |
| par défaut (sans modificateur) | classe ou membre | seulement à l’intérieur de son package |
protected |
méthode ou attribut | à l’intérieur du package ou par les classes dérivées |
private |
méthode ou attribut | uniquement à l’intérieur de la classe |

L’intérêt des modificateurs d’accès est de permettre de contrôler l’accès aux membres de la classe depuis d’autres classes (ou leurs instances, les objets).
En effet, lorsqu’on exécute un programme, il n’est pas souhaitable que des objets viennent modifier le comportement interne d’un autre objet. Cela pourrait engendrer des comportements indésirables.
On souhaite donc isoler certains membres d’un objet de l’extérieur afin qu’il soit inaccessibles.
On appelle ceci l’encapsulation. C’est un des concepts fondamentaux de la POO.
Reprenons les classes développées pour les calculs arithmétiques.
La classe Calcul contient un résultat. Comment isoler ce résultat de l’extérieur pour qu’il ne soit pas modifiable ?
Comment le rendre accessible pour que l’on puisse en connaître la valeur ?
Une solution : on encapsule l’attribut resultat et on lui ajoute des accesseurs.
Les accesseurs sont aussi appelés:
getter
getsetter
setUtilisez le code suivant et essayez de compiler votre programme:
public abstract class Calcul {
private int resultat ;
public abstract void calculer(int a, int b);
public int getResultat() {
return resultat;
}
public void setResultat(int r) {
resultat = r;
}
public String toString() {
return "Le résultat de l'opération "+getClass().getSimpleName()+"";
}
}On constate que certaines classes contiennent des erreurs de compilation.
Ainsi, la ligne suivante pose problème :
Utilisons l’accesseur commençant par set (on l’appelle aussi setter) :
Idem pour la ligne suivante:
Utilisons l’accesseur commençant par get (on l’appelle aussi getter) :
L’attribut resultat est désormais inaccessible depuis toute classe qui n’est pas Calcul.
Il est donc protégé de toute modification extérieure. La classe contrôle ce qui peut être définit sur cet attribut.
Pourtant, si on observe attentivement, on constate que n’importe quelle classe peut appeler la méthode setResultat().
Est-ce souhaitable ?
Quel modificateur d’accès utiliser pour remédier à cela parmi ceux vus précédemments ?
Sur quel membre le placer ?
On souhaite se débarrasser du setter : en effet, il n’est pas souhaitable que le résultat soit modifiable de l’extérieur.
Ainsi dans la classe Addition (par exemple), on veut que le code suivant fonctionne:
Comment faire ?
Dessinez la représentation UML de Calcul et de ses sous-classes.
Nous allons créer les classes suivantes dans le paquet com.example.java.voyage.
Des erreurs vont apparaître dans le code.
Commentez en indiquant pour chaque ligne:
Corrigez l’erreur en :
Note:
Un accesseur est une méthode permettant d’accéder ou de modifier la valeur d’un attribut
Vous pouvez expérimenter dans votre IDE.
Dans le fichier Trousse.java:
package com.example.java.voyage;
public class Trousse { /* La classe est visible partout */
public String publique ; /* Est visible partout où sa classe est visible*/
protected int protege ;
int defaut;
private int prive;
Trousse(String valPub, int valProt, int valDef, int valPriv){
publique = valPub;
protege = valProt;
defaut = valDef;
prive = valPriv;
}
Trousse(){
/* ... */
}
/** Accesseur public */
public int getProtege(){
return protege;
}
/** Accesseur public */
public int getPrive(){
return prive;
}
}Dans le fichier SacDeVoyage.java :
package com.example.java.voyage; //Meme paquet que Trousse
class SacDeVoyage {
Trousse trousse = new Trousse();
int entier;
String chaine;
SacDeVoyage(){
chaine = trousse.publique;
entier = trousse.protege;
entier = trousse.getProtege();
entier = trousse.defaut;
entier = trousse.prive ;
entier = trousse.getPrive();
}
}Dans le fichier TrousseDeToilette.java :
package com.example.java.voyage;
public class TrousseDeToilette extends Trousse {
int autreEntier ;
String autreChaine ;
public TrousseDeToilette() {
autreChaine = publique;
autreEntier = protege ;
autreEntier = defaut;
autreEntier = prive ;
autreEntier = getPrive();
}
}Nous allons créer la classe suivante dans le paquet com.example.java.transport.
package com.example.java.transport; //Un autre paquet
import com.example.java.voyage.Trousse; //import de Trousse
class Voiture {
Trousse trousse = new Trousse();
int entier;
String chaine;
Voiture(){
chaine = trousse.publique;
entier = trousse.protege;
entier = trousse.getProtege();
entier = trousse.defaut;
entier = trousse.prive ;
entier = trousse.getPrive();
}
}Puis la classe TroussePremierSecours :
package com.example.java.transport;
import com.example.java.voyage.Trousse;
public class TroussePremierSecours extends Trousse {
TroussePremierSecours(){
String chaine = publique;
int entier = protege;
entier = getProtege();
entier = defaut;
entier = prive ;
entier = getPrive();
}
}Corrigez toutes les erreurs (et expliquez en commentaire ce que vous avez fait et pourquoi) :
Dessinez la représentation UML des classes ainsi corrigées
Ce mot clé est très utile dans le cadre des setters.
En effet, dans la méthode setData(String data) suivante, comment accéder à l’attribut de l’objet data sachant que celui-ci est masqué par l’identifiant du paramètre data ?
class Information{
private String data ; //attribut
public void setData(String data){ //data est un paramètre
data = data ; // !!!
}
public void getData(){
return data ; // on renvoie la valeur de l attribut data
}
}L’appel à data correspond ici uniquement au paramètre nommé data.
Pour accéder à l’attribut, on le fait précéder du mot clé this.
this pointe vers l’instance de l’objet sur lequel s’applique la méthode.
Même si data est privé, on a le droit d’y accéder ici, puisqu’on le fait depuis l’intérieur de la classe.
Reprendre la classe Personne et rendre tous ses attributs inaccessibles depuis l’extérieur.
Mettre des getters pour tous les attributs.
Mettre des setters pour tous les attributs sauf nom, prenom et dateNaissance.
Ces trois attributs devront être positionnés/modifiés via un autre moyen que les accesseurs. Lequel ?
Est-ce logique de faire ainsi ?
Il est parfois nécessaire de convertir un type en un autre. Par exemple, on peut souhaiter convertir un entier en double.
Le compilateur ne laisse pas passer ce genre d’erreur. Pour remédier à cela, on utilise le transtypage (on utilise aussi le mot cast):
Il est possible de faire cela avec des objets:
Voici un diagramme de classe :

Dans ce qui suit, pour réaliser des calculs de distance, vous pouvez utiliser la classe Math (en utilisant éventuellement les static import).
Point qui décrit un point dans un repère en 2 dimensions avec des coordonnées entières (abscisse et ordonnée) et un nom (non modifiable).Les informations du point doivent être encapsulées et en lecture seule (getter uniquement). On autorise ainsi la modification des coordonnées du point uniquement par le biais de la méthode translater. 2. Ajouter un constructeur complet qui prend en paramètres le nom et les coordonnées du point. 3. Vérifier que vous ne pouvez pas modifier le nom en dehors du constructeur. Pour cela rajouter un setter sur cet attribut et compiler la classe Point. 4. Implémenter le code des deux méthodes de la classe Point:
distance(...) : renvoie la distance de l’instance courante à celle d’un autre point passé en paramètre,translater(...) : translate l’instance courante d’un vecteur de déplacement passé en paramètre.String toString() permettant de représenter l’instance de Point par une chaîne de caractères de la forme nom(abscisse, ordonnee).ApplicationPoint pour tester votre classe Point : le programme crée un point A de coordonnées (3, 5) et l’affiche sur la console.Prenez le soin de vérifier les valeurs données par le programme.