Utiliser les Outils de Java et Concevoir des Systèmes Flexibles
1. Introduction à la Bibliothèque Standard (API Java)
Java est bien plus qu'un simple langage de programmation ; c'est un écosystème complet. Le cœur de cet écosystème est son API (Application Programming Interface), une collection massive de classes et de packages préexistants.
Pensez-y comme à une boîte à outils géante fournie avec le langage lui-même. Un développeur Java ne passe pas son temps à réinventer la roue en codant à partir de zéro des solutions à des problèmes courants. Au contraire, il utilise les outils déjà disponibles dans cette bibliothèque standard.
Pourquoi l'API est-elle si Importante ?
→ Efficacité
Les classes de l'API sont optimisées et testées par des millions de développeurs. Plutôt que d'écrire votre propre code pour lire un fichier ou trier une liste, vous appelez simplement une méthode de l'API.
→ Standardisation
L'API garantit que les programmes Java fonctionnent de manière cohérente sur toutes les plateformes. Un programme utilisant la classe java.util.Date se comportera de la même manière sur Windows, macOS ou Linux.
→ Fonctionnalités Riches
L'API couvre une multitude de domaines, des collections de données (ArrayList, HashMap) à la gestion des entrées-sorties (Scanner, File), en passant par les mathématiques (Math).
Conseil pour Débuter
Lorsque vous avez besoin d'une fonctionnalité pour un nouveau projet, la première étape devrait être de vous demander : "Existe-t-il déjà une classe dans l'API Java qui fait cela ?" Une simple recherche en ligne vous mènera souvent directement à la bonne classe.
2. Les Collections Fondamentales : Au-delà des Tableaux
Les tableaux (int[]) sont rigides car leur taille est fixe. Le Framework des Collections de Java offre des structures de données plus puissantes et flexibles.
ArrayList : La Liste Dynamique
C'est la collection la plus utilisée. Elle permet de créer des listes dont la taille peut augmenter ou diminuer dynamiquement.
Génériques et Classes Enveloppes
Quand vous déclarez une ArrayList, vous devez spécifier le type d'objets qu'elle contiendra entre chevrons <>. C'est ce qu'on appelle les génériques.
ArrayList<String> fruits; // Une liste qui ne peut contenir QUE des String
Important : Les collections ne peuvent contenir que des objets, pas des types primitifs. Pour stocker des int, on utilise la classe enveloppe Integer.
L'API java.nio (New I/O) simplifie la lecture et l'écriture dans des fichiers.
import java.nio.file.Path;
import java.nio.file.Files;
import java.io.IOException;
try {
Path chemin = Path.of("monFichier.txt");
Files.writeString(chemin, "Bonjour, monde !"); // Écrit dans le fichier
String contenu = Files.readString(chemin); // Lit le fichier
System.out.println(contenu);
} catch (IOException e) {
e.printStackTrace();
}
4. Le Pilier de l'Abstraction : Interfaces et Classes Abstraites
L'abstraction est un concept clé pour gérer la complexité. Elle consiste à cacher les détails d'implémentation pour n'exposer que les fonctionnalités essentielles.
Interfaces : Le Contrat de Comportement
Une interface est un "contrat" qui définit un ensemble de méthodes qu'une classe doit implémenter. Elle définit ce qu'un objet est capable de faire.
// Contrat : tout objet "Volant" DOIT pouvoir décoller
interface Volant {
void decoller();
}
class Avion implements Volant {
@Override
public void decoller() {
System.out.println("L'avion utilise ses réacteurs.");
}
}
class Oiseau implements Volant {
@Override
public void decoller() {
System.out.println("L'oiseau utilise ses ailes.");
}
}
Classes Abstraites : Le Modèle à Compléter
Une classe abstraite est une classe qui ne peut pas être instanciée. C'est un modèle de base, partiellement construit, qui peut contenir du code commun et des parties à compléter.
// Modèle : un Animal a un nom, mais son cri est spécifique
abstract class Animal {
private String nom;
public Animal(String nom) { this.nom = nom; }
// Méthode abstraite : chaque sous-classe DOIT l'implémenter
public abstract void faireUnSon();
// Méthode concrète : le code est partagé
public void dormir() {
System.out.println(nom + " dort.");
}
}
class Chien extends Animal {
public Chien(String nom) { super(nom); }
@Override
public void faireUnSon() {
System.out.println("Ouaf !");
}
}
Interface vs Classe Abstraite : Comment Choisir ?
Classe Abstraite
Utilisez-la quand :
Vos classes partagent une identité commune
Vous avez du code commun à partager
Ex: Chien, Chat sont tous des Animal
Interface
Utilisez-la quand :
Vous voulez définir une capacité
Vos classes sont très différentes
Ex: Avion, Oiseau peuvent tous être Volant
Pour aller plus loin :
Source: EvoluNoob
Source: EvoluNoob
Résumé : Ce que Vous Avez Appris
Les Points Clés du Module 7
API Java - Une boîte à outils géante pour résoudre les problèmes courants
Collections - ArrayList, HashMap, HashSet pour gérer des groupes d'objets
Outils Utilitaires - Math, java.time, java.nio pour des tâches spécifiques
Abstraction - Interfaces et classes abstraites pour concevoir des systèmes flexibles
Choix de Design - Savoir quand utiliser une interface vs une classe abstraite
Exercices Pratiques : Utiliser la Boîte à Outils de Java
Mettez en pratique vos nouvelles connaissances sur les collections et l'abstraction pour résoudre des problèmes concrets.
Exercice 1 : Gestionnaire de Tâches avec `ArrayList`
Créez un programme simple qui gère une liste de tâches à faire. Le programme doit permettre d'ajouter une nouvelle tâche à la liste, de supprimer une tâche par son numéro, et d'afficher toutes les tâches restantes.
Indice : Utilisez une ArrayList<String>. Pour afficher les tâches avec leur numéro, utilisez une boucle for classique avec un compteur. Pour la suppression, rappelez-vous que les indices commencent à 0.
Voir la solution
import java.util.ArrayList;
import java.util.Scanner;
public class GestionnaireTaches {
public static void main(String[] args) {
ArrayList<String> taches = new ArrayList<>();
taches.add("Apprendre les ArrayList");
taches.add("Faire les courses");
System.out.println("--- Tâches Actuelles ---");
for (int i = 0; i < taches.size(); i++) {
System.out.println((i + 1) + ". " + taches.get(i));
}
// Supprimer la première tâche
taches.remove(0);
System.out.println("\n--- Tâches Mises à Jour ---");
for (int i = 0; i < taches.size(); i++) {
System.out.println((i + 1) + ". " + taches.get(i));
}
}
}
Exercice 2 : Annuaire Téléphonique avec `HashMap`
Créez un petit annuaire téléphonique. Le programme doit stocker des noms et des numéros de téléphone. Il doit être possible d'ajouter un nouveau contact et de rechercher le numéro d'un contact en donnant son nom.
Indice : Utilisez une HashMap<String, String> où la clé est le nom (unique) et la valeur est le numéro de téléphone. Utilisez annuaire.put("Nom", "Numéro") pour ajouter et annuaire.get("Nom") pour rechercher.
Voir la solution
import java.util.HashMap;
public class Annuaire {
public static void main(String[] args) {
HashMap<String, String> contacts = new HashMap<>();
// Ajout de contacts
contacts.put("Alice", "06 11 22 33 44");
contacts.put("Bob", "07 55 66 77 88");
contacts.put("Charlie", "01 99 88 77 66");
// Recherche d'un contact
String nomRecherche = "Bob";
String numeroTrouve = contacts.get(nomRecherche);
if (numeroTrouve != null) {
System.out.println("Le numéro de " + nomRecherche + " est : " + numeroTrouve);
} else {
System.out.println("Le contact '" + nomRecherche + "' n'a pas été trouvé.");
}
}
}
Exercice 3 : L'Orchestre (Interface `Instrument`)
Mettez en pratique l'abstraction et le polymorphisme en simulant un orchestre.
Créez une interface `Instrument` avec une méthode `void jouer()`.
Créez deux classes, `Piano` et `Violon`, qui implémentent cette interface. Chaque classe doit fournir sa propre version de `jouer()` (ex: "Le piano joue une mélodie." / "Le violon joue un arpège.").
Dans votre `main`, créez une ArrayList<Instrument>, ajoutez-y un piano et un violon, puis parcourez la liste pour faire jouer tous les instruments.
Indice : Ce problème est très similaire à l'exemple `Dessinable` du cours. Votre liste sera de type `Instrument`, mais pourra contenir des objets `Piano` et `Violon`.
Voir la solution
// Fichier: Instrument.java (Interface)
public interface Instrument {
void jouer();
}
// Fichier: Piano.java
public class Piano implements Instrument {
@Override
public void jouer() {
System.out.println("Le piano joue une mélodie douce.");
}
}
// Fichier: Violon.java
public class Violon implements Instrument {
@Override
public void jouer() {
System.out.println("Le violon joue un arpège vibrant.");
}
}
// Fichier: Orchestre.java
import java.util.ArrayList;
public class Orchestre {
public static void main(String[] args) {
ArrayList<Instrument> instruments = new ArrayList<>();
instruments.add(new Piano());
instruments.add(new Violon());
System.out.println("L'orchestre commence à jouer :");
for (Instrument instrument : instruments) {
instrument.jouer(); // Le polymorphisme en action !
}
}
}