Dans cette première partie, nous allons découvrir Java sous la forme de petits programmes. Nous n’allons pas tout de suite chercher à faire de programmes complexes, mais nous allons utiliser des mécanismes de la Programmation Orienté Objet et observer leurs effets.
L’idée va être de se familiariser avec différents concepts: classes, instances, interfaces, héritage et même modèles de conception.
Nous allons faire collaborer des objets entre eux afin d’observer des comportements selon la manière dont ils sont assemblés.
Dans cette partie, des exemples sont donnés pour chaque élément de base du langage.
La documentation Java fournie par Oracle est disponible ici. Elle reprend l’ensemble des concepts abordés;
Dupliquer la classe HelloWorld en une classe TypesPrimitifs (essayez un copier-coller).
Y insérer le code suivant:
int entier = 3;
System.out.print("entier: ");
System.out.println(entier);
boolean test = false;
System.out.print("booléen: ");
// Afficher cette valeur avec un System.out.println()
float flottant = 2.8f;
System.out.print("flottant: ");
// Afficher cette valeur avec un System.out.println()
//Voir le tableau ci-dessousDéterminez pourquoi des erreurs de compilation apparaissent avec les types et certaines valeurs ci-dessous :
Pour chacun des types, trouvez quelle est la valeur par défaut.
Si besoin, vous pouvez trouver plus d’information sur les types primitifs ici
En Java, les types tableaux (array) sont indexés à partir de 0.
Ils sont déclarés grâce à des crochets: []
Il est possible de créer des tableaux pour tous les types primitifs, mais aussi pour des objets (par exemple le type String).
Pour créer un nouveau tableau, plusieurs possibilités.
Créez une classe Tableaux* dans laquelle vous testerez les codes donnés ci-dessous.*
La première, en initialisant le tableau puis chacun de ses éléments:
tableauEntiers = new int[3];
tableauEntiers[0] = 1 ; //premier élément
tableauEntiers[1] = 2 ; //second élément
tableauEntiers[2] = 3 ; //troisième élément
System.out.print("premier élément:");
System.out.println(tableauEntiers[0]);
//...La seconde, en initialisant le tableau puis en lui attribuant un ensemble de valeur:
int[] tableauEntiers = {1_000, 2_345_678, 3, 4, 500000,
600_000_000, 7_000_000};
System.out.print("premier élément:");
System.out.println(tableauEntiers[0]);
//...Plus d’informations sur les tableaux sont disponibles ici
Définir un tableau à deux dimensions contenant quatre String.
"Nom" et "Prénom""Myriam" et "Makeba"Afficher chacune de ces valeurs séparéments.
Nous allons expérimentez quelques éléments sur les opérateurs dans une nouvelle classe Operateurs (toujours dans le paquet com.example.hello).
Pour une référence plus complète, vous pouvez trouver des informations ici
L’assignation de valeur se fait grâce au signe = :
Les opérations arithmétiques simples sont résumées ici:
| Opérateur | Description |
|---|---|
| + | Addition (ou pour le type String : concaténation) |
| - | Soustraction |
| * | Multiplication |
| / | Division |
| % | Modulo (reste de la division euclidienne) |
Exercice
Testez les codes suivants et vérifiez leur validité (est-ce que le résultat produit est bien le résultat attendu ?)
System.out.println("Hello" + " " + "World");
System.out.println( 1 + 3);
System.out.println("1" + 3);
System.out.println(1.0 + 3);
int dividende = 24;
int diviseur = 5;
System.out.println("Le résultat de " +
dividende +" % " + diviseur + " est " + dividende % diviseur);
System.out.println("Le résultat de " +
dividende +" / " + diviseur + " est " + dividende / diviseur);
double dividendeFlottant = 24.0;
System.out.println("Le résultat de " +
dividendeFlottant +" % " + diviseur + " est " + dividendeFlottant % diviseur);
System.out.println("Le résultat de " +
dividendeFlottant +" / " + diviseur + " est " + dividendeFlottant / diviseur);Les opérateurs de comparaisons sont les suivants:
| Opérateur | Description |
|---|---|
| == | égal |
| != | non égal (différent de) |
| > | supérieur |
| >= | supérieur ou égal |
| < | inférieur |
| <= | inférieur ou égal |
Ils renvoient toujours une valeur booléenne (boolean).
Testez les codes suivants et vérifiez leur validité (est-ce que le résultat produit est bien le résultat attendu ?)
int un = 1;
System.out.println("1 == 2 : " + (1 == 2));
System.out.println("2 == 1 + 1 : " + (2 == 1 + un));
System.out.println("1 != 2 : " + (1 != 2));
System.out.println("3 > 3 : " + (3 > 3));
System.out.println("3 >= 3 : " + (3 >= 3));
System.out.println("4 < 4 : " + (4 < 4));
System.out.println("4 <= 4 : " + (4 <= 4));Les opérations ET, OU et NON se font sur des valeurs booléennes:
| Opérateur | Description |
|---|---|
|| |
OU |
&& |
ET |
! |
NON |
Testez les codes suivants et vérifiez leur validité (est-ce que le résultat produit est bien le résultat attendu ?)
int un = 1;
System.out.println("false || false : " + (false || false));
System.out.println("false || true : " + (false || true));
System.out.println("true || true : " + (true || true));
System.out.println("false && true : " + (false && true));
System.out.println("true && true : " + (true && true));
System.out.println("2 == 1 + un && true : "+ (2 == 1 + un || true));
System.out.println("NON (2 == 1 + un && true) : "+ !(2 == 1 + un || true));Reprenez chacun des codes précédents et lancez-le en utilisant le déboggueur Eclipse (Menu Run > Debug ou le bouton de la barre d’outils ayant l’icône correspondante)
Acceptez le passage dans la Perspective correspondante au mode Debug
Ajoutez un point d’arrêt sur la première ligne de votre méthode main et relancez le débogueur.
Visualisez les boutons Step into, Step over.
Java est un langage Orienté Objet (OO). Cela signifie que programmer consiste à définir des entités qui vont contenir des données et des comportements. Le programme indique comment ces entités vont interagir entre elles.
Ces entités sont des objets.
Note: On parle de Programmation Orientée Objet (POO). En anglais: OOP (Object Oriented Programing)
Pour créer un objet, il faut un modèle (un patron, un moule).
Le modèle d’un objet est une classe.
À partir de ce modèle, on en créera un exemplaire : un objet est une instance d’une classe.
Parfois, on utilise le mot type pour désigner une classe. Par exemple, un objet de type Integer désigne une instance de la classe Integer.
Chaque objet possède des membres :
Une classe permet de définir ces membres (attributs et méthodes) pour tous les objets qui seront instanciés sur son modèle.
Une méthode est l’équivalent d’une fonction en programmation procédurale; sauf que cette fonction permet de manipuler les attributs de l’objet, indépendamment de ceux d’un autre objet.
Dans un premier temps, il vous est proposé de créer une fonction mathématique permettant de multiplier deux nombres entiers.
Le résultat de cette fonction sera stocké dans l’attribut resultat de l’objet
Implémenter une méthode (que l’on nommera calculer) dans une classe nommée Multiplication
Voici un exemple à compléter:
package com.example.java;
public class Multiplication {
int resultat ;
public void calculer(int a, int b){
resultat = a * b;
}
}Un peu d’UML : ci-dessous la représentation UML de cette classe

Pour tester cette classe, nous allons créer une nouvelle classe principale (qui contient une méthode main) dans laquelle on fera appel à la classe Multiplication.
Cette nouvelle classe se nommera Calculer:
package com.example.java ;
public class Calculer {
public static void main(String[] args) {
//Créer une instance de la nouvelle classe avec le mot clé `new`
Multiplication premierCalcul = new Multiplication();
// Créer une variable nommée resultat
premierCalcul.calculer(3, 5); // appel de méthode
// Ecrire le résultat du calcul dans la sortie standard
System.out.println("Le résultat de 3 multiplié par 5:");
System.out.println(premierCalcul.resultat);
}
}Dans ce programme, nous avons utilisé le mot clef new qui permet d’instancier un objet à partir d’une classe:
Ce mot clef permet de faire appel au constructeur de la classe. Si aucun constructeur n’est explicitement déclaré dans une classe, le compilateur Java crée un constructeur par défaut, c’est-à-dire sans aucun paramètre.
La ligne ci-dessus stocke un pointeur vers l’instance créée dans la variable premierCalcul.
Cette variable est déclaré avec un type (la classe) Multiplication.
L’appel d’une méthode est similaire à l’appel d’une fonction dans un autre langage, à la différence près que la méthode est rattachée à un objet.
La ligne suivante permet donc d’appeler la méthode calculer qui est rattachée à l’instance pointée par la variable premierCalcul.
Exécuter votre programme depuis Eclipse
Que constatez-vous ?
Implémentez l’opération mathématique Addition. Elle permet d’additionner deux nombres entiers dans une classe nommée Addition, sur le même modèle que la classe Multiplication.
Testez-les avec un code qui devrait ressembler à ceci (toujours dans la classe principale Calculer:
Addition secondCalcul = new Addition(); //Instanciation
secondCalcul.calculer(3, 5); //appel de la
System.out.println("Le résultat de 3 ajouté à 5:");
System.out.println(secondCalcul.resultat);Essayez d’appeler plusieurs fois la méthode additionner sur une même instance et observer l’effet sur l’attribut resultat.
Faites de même sur plusieurs instances différentes (stockées dans des variables troisiemeCalcul, quatriemeCalcul, ou calcul3, calcul4, calcul5, etc).
Que constatez-vous ? Qu’en déduisez-vous ?
Une piste: est-ce que les attributs resultat des différentes instances ont la même valeur ? Quel est l’intérêt de ceci ?
Reprenez chacun des codes précédents et lancez-le en utilisant le déboggueur Eclipse
Ajoutez un point d’arrêt sur la première ligne de votre méthode calculer et relancez le débogueur.
Visualisez les boutons Step into, Step over et Step return.
Visualisez la zone Variables (en haut à droite)
Une des particularité de la POO est qu’une classe peut hériter d’une autre classe. Cela a plusieurs avantages, notamment celui de permettre la réutilisation de code déjà écrit.
Ainsi, une classe peut hériter des comportements (méthodes) et données (attributs) d’une classe parente.
Nous allons observer cela en modifiant le programme réalisé précédemment. Pour cela, nous allons créer une classe Calcul qui contiendra un attribut resultat. Cet attribut ne sera pas déclaré une seconde fois dans les classes qui en héritent.
Fichier Calcul.java :
Fichier Multiplication.java :
package com.example.java;
public class Multiplication extends Calcul {
public void calculer(int a, int b){
resultat = a * b;
}
}En relançant le programme précédent, cela devrait continuer à fonctionner.
Nous observons l’utilisation du mot clé extends qui signifie que la classe Multiplication hérite de la classe Calcul.
On peut dire ceci:
Calcul est la classe parente de la classe MultiplicationMultiplication est une classe fille de la classe CalculUn peu d’UML : voici un diagramme de classe qui représente cet héritage

On remarque ici que la classe Calcul hérite de la classe Object. La raison est simple: toute classe en Java hérite toujours de la classe Object. C’est logique, puisque tout est objet en Java.
Adapter la classe Addition pour correspondre au diagramme suivant:

Nous allons maintenant écrire une classe Soustraction qui va hériter de la classe Addition contenant la méthode suivante :
calculer permettant de soustraire deux nombres entiers .Il serait logique ici de dire que cette classe hérite d’Addition puisqu’une soustraction consiste à additionner au premier opérande l’opposé du second opérande : resultat = a + (-b)
Il est possible d’appeler une méthode de la classe parente (la classe de niveau supérieur) grâce au mot clé super:
Soustraction et exécuter votre programme.D’une manière générale, on peut considérer que Multiplication, Addition et Soustraction sont des calculs arithmétiques.
Ces classes ont toutes en commun une méthode nommée calculer. D’ailleurs, lors des appels de ces méthodes on avait toujours quelque chose de cette forme:
Nous pouvons déclarer cette méthode directement dans la classe Calcul et nous allons la déclarer comme étant abstraite. Calcul sera une abstraction des autres opérations.
Pour cela, nous allons d’abord modifier la classe Calcul:
Puis nous allons remplacer les types des variables par le type Calcul dans la classe Calculer:
public class Calculer {
public static void main(String[] args) {
Calcul premierCalcul = new Multiplication();
premierCalcul.calculer(3, 5); // appel de méthode
System.out.println("Le résultat de 3 multiplié par 5:");
System.out.println(premierCalcul.resultat);
//...
}
}On constate ici que la compilation passe et que le programme se comporte exactement de la même manière.
Alors quel est l’intérêt de procéder ainsi ? Essayez de remplacer l’un des constructeurs des sous-classes de Calcul par l’un des autres et ré-exécutez le programme pour observer les effets.
Le diagramme de classes ci-dessous représente cette classe abstraite, ajoutez-y la classe Soustraction:

Dans l’exemple précédent, on fait une généralisation: Calcul généralise les classes Multiplication, Addition et Soustraction.
A l’inverse, les classes Multiplication, Addition et Soustraction héritent de la classe Calcul: on dit aussi que ces classe spécialisent la classe Calcul. Elles sont spécialisées pour une opération donnée.
Nous allons maintenant observer l’héritage dans la documentation de Java.
Ouvrez la documentation JAVA 8 qui se trouve ici : https://docs.oracle.com/javase/8/docs/api/index.html?overview-summary.html
Les chaînes de caractères en Java sont gérées par la classe String.
Essayez de trouver la classe String dans cette documentation.
Faites un diagramme UML représentant cette classe (avec au moins sa classe parente).
Toute classe Java hérite toujours de la classe Object. Cette classe contient deux méthodes intéressantes: getClass() et toString()
Nous allons expérimenter cela dans ce qui suit.
Nous allons partir de notre programme Hello World pour lui ajouter quelques fonctionnalités.
Pour cela, nous allons dupliquer cette classe avec notre explorateur de fichier (sans utiliser les fonctions d’Eclipse) et en renommant le fichier Exemple.java (toujours dans le même répertoire).
Une fois cela fait, essayez de compiler et de lancer le programme. Que constatez-vous ?
Vous allez modifier le main(String[]) en remplaçant le system.out.println comme suit:
public static void main(String[] args) {
Object instance = new Exemple();
System.out.println(instance); // Affiche
}Lancez le programme (en sélectionnant la classe Exemple comme classe à exécuter). Que constatez-vous ?
Maintenant, vous allez modifier la classe en ajoutant une méthode nommée toString() :
Dans cet exemple, nous venons de concaténer deux chaînes de caractères. C’est l’opérateur + qui permet cela : l’instruction "ab" + "cd" renvoie la valeur "abcd".
Relancez le programme. Que constatez-vous ?
À nouveau, vous allez modifier la classe en modifiant la méthode toString() :
Relancez le programme. Que constatez-vous ?
Avez-vous des questions ? A quoi sert la méthode toString() ?
Faites un diagramme UML représentant cette classe Exemple ainsi que la classe Object. Représentez également la classe String sur ce diagramme
Nous allons définir une classe personne comme suit:
public class Personne {
String nom;
String prenom;
String dateNaissance;
String adresseMail;
String telephone;
public static void main(String[] args) {
Personne utilisateur = new Personne();
utilisateur.nom = "McEnroe";
utilisateur.prenom = "John";
utilisateur.dateNaissance = "10/10/1960";
utilisateur.adresseMail = "johnmcenroe@usa.tennis.com";
utilisateur.telephone = "+001 203 204 205";
System.out.println(utilisateur.nom);
System.out.println(utilisateur.prenom);
System.out.println(utilisateur);
}
}Exécutez ce programme. Que constatez-vous ?
Les attributs de cette classe sont:
Aux attributs de cette classe, on va pouvoir rajouter des méthodes:
public class Personne {
String nom;
String prenom;
String dateNaissance;
String adresseMail;
String telephone;
public static void main(String[] args) {
Personne utilisateur = new Personne();
utilisateur.nom = "McEnroe";
utilisateur.prenom = "John";
utilisateur.dateNaissance = "10/10/1960";
utilisateur.adresseMail = "johnmcenroe@usa.tennis.com";
utilisateur.telephone = "+001 203 204 205";
System.out.println(utilisateur.nom);
System.out.println(utilisateur.prenom);
System.out.println(utilisateur);
}
public String getNomPrenom(){
return nom+" "+prenom; //Concaténation des chaines nom, " " et prenom
}
public String getPrenomNom(){
return prenom+" "+nom;
}
}Ces méthodes sont des méthodes d’instance: elles sont liées à un exemplaire de la classe Personne. On peut les utiliser en ajoutant à la fin de la méthode main(String[]) les lignes suivantes:
Que constatez-vous ?
Nous allons maintenant modifier l’affichage obtenu avec la ligne suivante du main(String[]):
Pour cela, nous surchargeons la méthode toString qui était déjà définie dans la classe Object:
Que constatez-vous ?
Vous allez maintenant reprendre les classes Calcul et ses sous-classes. Modifiez la méthode toString() de cette classe pour que le code suivant:
Produise exactement la sortie suivante une fois exécutée:
Le résultat de l'opération Multiplication de 4 et 8 donne 32.
Vous avez la possibilité de rajouter de nouveaux attributs à vos classes afin de stocker (par exemple) les opérandes ou toute information utile.
Dans la classe Personne, nous avons utilisé des chaînes de caractères avec l’opérateur + : nous avons concaténé des chaînes de caractères entre elles.
Nous allons utiliser ici la classe String afin d’en découvrir quelques aspects importants.
Exécuter le programme suivant:
public class ExerciceChaine {
public static void main(String[] args) {
String uneChaine = "Bonjour" ;
String autreChaine = "Bonjour" ;
ExerciceChaine ec = new ExerciceChaine();
System.out.println("-- Deux chaines identiques");
ec.testChaines(uneChaine, autreChaine);
System.out.println("-- Une nouvelle instance");
autreChaine = new String("Bonjour");
ec.testChaines(uneChaine, autreChaine);
System.out.println("-- Une concaténation simple");
autreChaine = "Bon" + "jour" ;
ec.testChaines(uneChaine, autreChaine);
System.out.println("-- Une concaténation avec des variables différentes");
autreChaine = "Bon" ;
String troisiemeChaine = "jour";
autreChaine = autreChaine + troisiemeChaine;
ec.testChaines(uneChaine, autreChaine);
}
public void testChaines(String a, String b){
if(a == b){
System.out.println("Les chaînes '"+ a + "' et '"+b+ "' sont les mêmes");
}
else{
System.out.println("Les chaînes '"+ a + "' et '"+b+ "' sont différentes");
}
}
}Remplacez la méthode testChaines(String, String) par la suivante:
public void testChaines(String a, String b){
if(a.equals(b)){
System.out.println("Les chaînes '"+ a + "' et '"+b+ "' sont les mêmes");
}
else{
System.out.println("Les chaînes '"+ a + "' et '"+b+ "' sont différentes");
}
}Que constatez-vous ?
Allez voir dans la Javadoc à quoi correspond la méthode equals(Object).
Pourquoi est-elle utile ?
Exécutez le programme suivant:
public static void main(String[] args) {
String chaine = "Quelques caractères";
System.out.println(chaine.length());
System.out.println(chaine.substring(2));
System.out.println(chaine.substring(5,10));
System.out.println(chaine.startsWith("Que"));
System.out.println(chaine.startsWith("que"));
System.out.println(chaine.endsWith("res"));
System.out.println(chaine.endsWith("re"));
System.out.println(chaine.indexOf("ra"));
System.out.println(chaine.toLowerCase());
System.out.println(chaine.toUpperCase());
}Aidez-vous de la Javadoc pour comprendre ce que font chacune de ces méthodes.
En utilisant la chaîne " Je suis une chaîne moi aussi " (attention aux espaces en début et fin de chaîne), testez les effets des méthodes suivantes:
lastIndexOf(String)trim()toString()Que constatez-vous ? Est-ce logique ?
Nous allons utiliser une boucle simple pour récupérer chaque caractère d’une chaîne.
Analysez le code ci-dessus et posez des questions si vous ne le comprenez-pas.
Ecrivez un programme qui détermine si une chaîne entrée au clavier est un palindrome (un mot qui se lit dans les deux sens).
Pour récupérer des chaînes de caractères entrés par un utilisateur voir l’annexe RecuperationDeDonneesDansLaConsole
La création d’objet en Java se fait avec le mot clef new.
L’opération effectuée avec new est appelée une instantiation: on crée une instance (c’est-à-dire un “exemplaire”) d’une classe.
Cette instance est un exemplaire indépendant des autres objets de cette classe.
Vous allez implémenter une classe nommée Fleur dans le paquet com.example.java.nature
Cette classe se fera sur le modèle suivant:

Implémentez cette classe de sorte que toString() renvoie une valeur ressemblant à nomDeLaFleur(3) (avec nom = "nomDeLaFleur" et identifiant = 3
Essayez d’instancier cette classe à partir de la méthode main(String[]) de Exemple et d’afficher cette instance avec un System.out.println(String).
Que constatez-vous ?
Est-on limité par quelque chose ici ?
Pour pouvoir créer cette classe, il existe un constructeur par défaut. Sauf qu’il ne permet pas de modifier les valeurs des attributs.
Créer un nouveau constructeur sur le modèle suivant:
Essayez d’utiliser ce constructeur et d’afficher l’instance depuis la méthode main(String[])
Créez ainsi plusieurs instances de Fleur et affichez-les.