Un objet est une instance d’une classe. Il représente une entité réelle ou conceptuelle avec ses propres attributs (champs) et comportements (méthodes).
Les Références
Une référence est une valeur qui pointe vers un objet en mémoire. Elle est stockée dans une variable.
null: Une référence peut avoir la valeur null, indiquant qu’elle ne pointe vers aucun objet.
Opérateurs sur les références:
Accès aux champs:objet.champ
Appel de méthodes:objet.methode()
Transtypage (cast):(Type)objet
Concaténation de chaînes:chaine + objet (appelle objet.toString())
instanceof: Vérifie si un objet est d’un certain type (objet instanceof Type)
Comparaison:== compare les références (si elles pointent vers le même objet), != compare l’inverse.
La classe Object est la classe de base de toutes les classes en Java. Cela signifie que toutes les classes, même si vous ne les en faites pas explicitement hériter, héritent indirectement de Object.
Rôle de la classe Object
Classe racine: Tous les objets en Java sont des instances de Object ou de ses sous-classes.
Méthodes de base: Fournit un ensemble de méthodes de base que toutes les classes peuvent utiliser ou redéfinir.
Méthodes principales de Object
getClass(): Retourne un objet de type Class représentant la classe de l’objet courant. Cette méthode est utilisée pour l’introspection, c’est-à-dire pour obtenir des informations sur la classe d’un objet à l’exécution.
toString(): Retourne une représentation sous forme de chaîne de caractères de l’objet. Par défaut, elle retourne le nom de la classe suivi de son hashcode.
equals(Object obj): Détermine si deux objets sont égaux. Par défaut, elle compare les références (c’est-à-dire si les deux objets sont le même objet).
hashCode(): Retourne un code hash, un entier qui sert à placer les objets dans des structures de données comme les HashMap.
clone(): Crée une copie de l’objet. Cette méthode doit être redéfinie dans les sous-classes pour permettre le clonage.
finalize(): Méthode appelée par le garbage collector juste avant de détruire un objet. Elle est rarement utilisée et peut entraîner des comportements imprévisibles.
Les Variables en Java (1/2)
En Java, les variables sont utilisées pour stocker des données. Leur portée et leur durée de vie varient en fonction de leur type.
Les différents types de variables
Type de variable
Portée
Durée de vie
Initialisation
Instance
Toute la classe
Par instance
Déclaration ou constructeur
Classe
Toute la classe
Une fois par classe
Lors du chargement de la classe
Locale
Bloc
Pendant le bloc
Déclaration
Tableau
Tableau
Tant que le tableau existe
Lors de la création du tableau
Paramètre de méthode
Méthode
Pendant la méthode
Passage d’arguments
Paramètre de constructeur
Constructeur
Pendant le constructeur
Passage d’arguments
Paramètre d’exception
Bloc catch
Pendant le bloc catch
Capture d’exception
Variables finales en Java
Immutable après initialisation.
Référence finale: pointe toujours vers le même objet, mais l’état de l’objet peut changer.
Variable d’instance finale: constante par instance.
Initialisation obligatoire: avant toute utilisation.
Valeurs par défaut: 0 pour les numériques, false pour les booléens, null pour les références.
Les méthodes en Java peuvent être classées en différentes familles selon leur rôle et leur visibilité :
Accesseurs et modificateurs : Permettent respectivement de lire et de modifier les attributs d’un objet.
Méthodes privées : Utilisées en interne à une classe, elles ne sont pas accessibles depuis l’extérieur.
Méthodes publiques : Constituent l’interface de la classe, elles sont accessibles depuis n’importe où.
Surcharge de méthodes
Définition: La surcharge consiste à définir plusieurs méthodes dans une même classe portant le même nom mais ayant des signatures différentes.
Signature d’une méthode: La signature d’une méthode est composée de : * Nom de la méthode: Le nom qu’on utilise pour appeler la méthode. * Liste des paramètres: Le nombre et le type des paramètres que la méthode prend en entrée.
Important: Le type de retour ne fait pas partie de la signature. Deux méthodes ne peuvent donc pas être surchargées uniquement en changeant leur type de retour.
Exemple
publicclass Voiture {// Instance variablesprivateString immatriculation;// Vehicle registration numberprivateString marque;// Brandprivateboolean enMarche;// Running status// ConstructorspublicVoiture(String immatriculation,String marque){this.immatriculation= immatriculation;this.marque= marque;this.enMarche=false;// Initialize running status to false}publicVoiture(String immatriculation){this(immatriculation,"");}// ModifierspublicvoidsetMarque(String marque){this.marque= marque;}// AccessorspublicStringgetImmatriculation(){return immatriculation;}publicStringgetMarque(){return marque;}publicbooleanisEnMarche(){return enMarche;}// Methodspublicvoiddemarrer(){if(!enMarche){ enMarche =true;System.out.println("La voiture démarre.");}else{System.out.println("La voiture est déjà en marche.");}}publicvoidarreter(){if(enMarche){ enMarche =false;System.out.println("La voiture s'arrête.");}else{System.out.println("La voiture est déjà arrêtée.");}}}
Figure 1: Les Voiture en UML
Figure 2: Les Voiture en UML
Les paramètres en Java : Passage par valeur
En Java, tous les paramètres sont passés par valeur.** Cela signifie qu’une copie de la valeur de chaque argument est transmise à la méthode appelée.
Cas particuliers des références
Modification de la référence: Si on tente de modifier la valeur de la référence elle-même à l’intérieur d’une méthode, cette modification n’aura aucun effet en dehors de cette méthode.
Modification de l’objet référencé: Si on modifie les propriétés de l’objet référencé par la référence passée en paramètre, ces modifications seront visibles en dehors de la méthode, car on travaille sur l’objet d’origine.
Exemple
class Voiture {privateString immatriculation;privateString marque;// ... constructeurs et getters/setters ...}publicclass Parametres {publicstaticvoidmain(String[] args){ Voiture uneVoiture =newVoiture("1234 AB 83"); uneVoiture.setMarque("Rolls-Royce");// La méthode changeMarque modifie l'objet uneVoiturechangeMarque(uneVoiture);System.out.println(uneVoiture);// Affiche toujours "Rolls-Royce"// La méthode abandonner ne modifie pas la référence uneVoitureabandonner(uneVoiture);System.out.println(uneVoiture);// Affiche toujours l'objet, même si la référence locale a été mise à null}privatestaticvoidabandonner(Voiture v){ v =null;// Cette modification n'a pas d'effet sur uneVoiture}privatestaticvoidchangeMarque(Voiture v){ v.setMarque("Fiat");// Modifie l'objet uneVoiture}}
Méthodes et variables de classe
Variables de classe (statiques)
Déclaration: Utiliser le mot-clé static pour déclarer une variable appartenant à la classe elle-même plutôt qu’à une instance particulière.
Constantes de classe: Lorsqu’une variable de classe est déclarée final, elle devient une constante pour l’ensemble du programme.
Initialisation: Les variables de classe sont initialisées lors du chargement de la classe.
Accès: Elles peuvent être accédées directement depuis la classe, sans avoir besoin d’instancier un objet.
Méthodes de classe (statiques)
Invocation: S’appellent directement à partir de la classe (e.g., NomDeLaClasse.nomDeLaMethode()).
Contexte: Ne peuvent accéder qu’à des variables et méthodes statiques.
Signature: Ne peuvent pas avoir la même signature qu’une méthode d’instance.
Bloc statique
Initialisation complexe: Utilisé pour effectuer des initialisations complexes de variables de classe, qui ne peuvent pas être faites directement dans la déclaration.
Exécution: S’exécute une seule fois, lors du chargement de la classe.
Pourquoi utiliser les méthodes et variables de classe ?
Partage: Les variables de classe sont partagées par toutes les instances de la classe.
Utilitaires: Les méthodes de classe peuvent être utilisées sans créer d’instance.
Constantes: Les constantes de classe sont idéales pour des valeurs qui ne changent jamais.
Exemple 1
publicclass MathUtils {publicstaticfinaldouble PI =3.14159;static{System.out.println("La classe MathUtils est chargée");}publicstaticintfactorielle(int n){// ...}}
Exemple 2
publicclass Chien {// AttributsprivateString tatouage;// Tatouage unique du chienprivateString nom;// Nom du chienprivatestaticint nbChiens =0;// Nombre total de chiens créésprivatestaticfinalint NB_REFUGES =3;// Nombre de refugesprivatestaticint[] occupationRefuge =newint[NB_REFUGES];// Occupation des refuges (-1: libre, 0: occupé)// ConstructeurpublicChien(String tatouage,String nom){this.tatouage= tatouage;this.nom= nom; nbChiens++;// Incrémente le nombre de chiens à chaque création}// Méthodes statiques pour gérer les informations globalespublicstaticintgetNbChiens(){return nbChiens;}// Méthodes pour gérer l'occupation des refugespublicstaticbooleanplacerDansRefuge(int numeroRefuge){if(numeroRefuge <0|| numeroRefuge >= NB_REFUGES){System.err.println("Numéro de refuge invalide");returnfalse;}if(occupationRefuge[numeroRefuge]==-1){ occupationRefuge[numeroRefuge]=0;returntrue;}else{System.err.println("Refuge déjà occupé");returnfalse;}}publicstaticbooleanretirerDeRefuge(int numeroRefuge){if(numeroRefuge <0|| numeroRefuge >= NB_REFUGES){System.err.println("Numéro de refuge invalide");returnfalse;}if(occupationRefuge[numeroRefuge]==0){ occupationRefuge[numeroRefuge]=-1;returntrue;}else{System.err.println.println("Refuge déjà libre");returnfalse;}}// Bloc statique pour initialiser le tableau des refugesstatic{for(int i =0; i < NB_REFUGES; i++){ occupationRefuge[i]=-1;}}}
Protection en Java : Niveaux d’accès
Le principe de base
En Java, la protection d’un élément (méthode ou attribut) définit l’ensemble des entités qui peuvent y accéder. Cette protection s’applique au niveau de la classe et non de l’objet.
Les différents niveaux d’accès
Modificateur
Dans la même classe
Dans le même package
Dans un sous-package
Depuis une autre classe
private
Oui
Non
Non
Non
(aucun)
Oui
Oui
Non
Non
protected
Oui
Oui
Oui
Non (sauf si sous-classe)
public
Oui
Oui
Oui
Oui
Exemple concret
publicclass Personne {/*** Le nom de la personne.* Cet attribut est privé pour garantir l'encapsulation des données.*/privateString nom;/*** L'âge de la personne.* Cet attribut est protégé pour permettre l'accès aux sous-classes.*/protectedint age;/*** L'adresse de la personne.* Cet attribut est public pour être accessible de n'importe où.*/publicString adresse;/*** Le numéro de téléphone de la personne.* Cet attribut est accessible uniquement depuis le même package.*/String telephone;// ... méthodes ...}
Structure d’un programme Java
Un programme Java est un ensemble de classes. Chaque classe définit un nouveau type d’objet. Pour qu’un programme soit exécutable, il doit contenir au moins une classe avec une méthode main.
La méthode main : le point d’entrée
Signature:public static void main(String[] args)
public : accessible de partout
static : appartient à la classe, pas à une instance
void : ne retourne rien
String[] args : tableau de chaînes de caractères pour les arguments en ligne de commande
Exemple : un programme simple
publicclass BonjourATous {publicstaticvoidmain(String[] args){System.out.println("Bonjour à tous !");}}
L’instanciation et les constructeurs
L’instanciation, c’est créer un objet (un instance) à partir d’une classe.
Le constructeur est une méthode spéciale qui :
A le même nom que la classe.
Est appelée automatiquement lors de la création d’un objet.
Sert à initialiser les attributs de l’objet.
Ne retourne aucune valeur.
Peut être surchargé.
Syntaxe d’instanciation:
Classe nomDeLaVariable =newClasse(paramètres);
Le constructeur par défaut
Création automatique:
Si vous ne définissez pas de constructeur, le compilateur en crée un par défaut.
Il est sans paramètres.
Il a la même visibilité que la classe.
Il initialise les attributs à leurs valeurs par défaut (null, 0, etc.).
publicclass Personne {privateString nom;privateint age;// Constructeur par défaut créé implicitement}Persone personne =newPersonne();
L’instanciation - Exemple
/*** Exemple d'instanciation des classes Voiture et Chien.**@author Emmanuel Bruno*@version0.2*/publicclass Instanciation {publicstaticvoidmain(String[] args){ Voiture uneVoiture =newVoiture("1234 AB 83"); uneVoiture.setMarque("Rolls-Royce"); uneVoiture.demarrer();System.out.println("uneVoiture est une "+ uneVoiture.getMarque()); Chien c1 =newChien("C1","Rex"); Chien c2 =newChien("C2","Médor");System.out.println("Il y a "+ Chien.getNbChiens()+" chiens");}}
Les références en Java : un lien vers l’objet
Qu’est-ce qu’une référence ?
C’est une variable qui pointe vers un objet en mémoire.
Elle ne contient pas l’objet lui-même, mais son adresse.
Allocation en mémoire (heap):
Lors de l’instanciation avec new, la mémoire est allouée dans le heap.
La référence obtenue pointe vers cette zone.
Destruction des objets (Garbage Collector):
Pas de destructeur explicite en Java.
Les objets sont détruits automatiquement lorsqu’ils ne sont plus référencés.
Passage de références en paramètre:
Une copie de la référence est passée.
Les deux références pointent vers le même objet.
Modifications de l’objet:
Toute modification via une référence est visible par les autres.
Durée de vie d’un objet:
Tant qu’au moins une référence pointe vers lui.
Le garbage collector libère la mémoire lorsqu’il n’y a plus de références.
Exemple
class RamasseMiette {publicstaticvoidmain(String[] args){{// Bloc pour limiter la portée de chien1 Chien chien1 =newChien("X1","Rex");// chien1 sera collecté à la fin de ce bloc}// Création d'un grand tableau pour consommer de la mémoireint[] grandTableau =newint[1000000];// Simule une grosse consommation mémoire// Boucle infinie (pour observer le comportement du GC)while(true){// Rien à faire ici, juste attendre que le GC s'exécute}}}
Le ramasse-miettes en Java : un gestionnaire de mémoire automatique
Qu’est-ce que c’est ?
Mécanisme automatique de libération de la mémoire.
Identifie les objets inutilisés et les détruit.
Pourquoi l’utiliser ?
Sécurité: Évite les fuites mémoire.
Simplicité: Délégation de la gestion mémoire à la JVM.
Comment ça marche ?
Algorithmes: Mark and Sweep, Copying, Generational.
Déclenchement:
Lorsqu’il y a un manque de mémoire.
À intervalles réguliers.
La méthode finalize()
Invocation: Juste avant la destruction d’un objet.
Utilité: Pour effectuer des opérations de nettoyage.
Limitations:
Ne garantit pas la destruction.
Appelée une seule fois.
À utiliser avec précaution.
Forcer le ramasse-miettes (mauvaise idée)java Runtime.getRuntime().gc();
Les tableaux en Java : un aperçu
Un tableau est un objet
Instancié avec new
Possède des propriétés (comme length)
Taille dynamique
Déclarée sans taille précise
Taille définie à la création avec new
Indexation à partir de 0
Premier élément : tableau[0]
Initialisation
Avec des valeurs par défaut: Toutes les valeurs sont initialisées à zéro (pour les types numériques), à null (pour les références).
Avec des valeurs explicites: Lors de la déclaration.
Accès à la taille
Propriété length : donne le nombre d’éléments du tableau.
Instanciation des éléments
Tableau de primitives: Les éléments sont des valeurs primitives.
Tableau de références: Le tableau contient des références vers des objets. Instancier le tableau ne crée pas les objets eux-mêmes.
Exemple:
int[] mesEntiers =newint[3];// Tableau de 3 entiersString[] mesChaines ={"Bonjour","monde"};// Tableau de 2 chaînesVoiture[] mesVoitures =new Voiture[3];// Tableau de 3 références vers des objets Voiture
Les chaînes de caractères en Java : un aperçu
Les chaînes sont des objets
Instance de la classe String
Immuables : une fois créée, une chaîne ne peut pas être modifiée
Littéraux
Écrits entre guillemets doubles (")
Deux littéraux identiques référencent le même objet
Opérations de base
Concaténation: Opérateur +
Comparaison: Méthodes equals() et compareTo()
Immuabilité
Une chaîne ne peut pas être modifiée après sa création
Toute opération de modification crée une nouvelle chaîne
Chaînes modifiables
StringBuffer: Synchronisée, adaptée à un environnement multi-thread
StringBuilder: Non synchronisée, plus performante en mono-thread
Exemple
String message ="Hello";// Création d'une chaînemessage = message +" world";// Création d'une nouvelle chaîneStringBuilder sb =newStringBuilder("Hello");sb.append(" world");// Modification du StringBuilder
Enveloppement des types primitifs en Java
Pourquoi des classes d’enveloppement ?
Traiter les types primitifs comme des objets: Permet d’utiliser des méthodes, de les placer dans des collections, etc.
Utiliser des constantes prédéfinies: Par exemple, Integer.MAX_VALUE.
Effectuer des conversions de types: Entre types primitifs et leurs équivalents objet.
Les classes d’enveloppement
Byte, Short, Integer, Long: Pour les nombres entiers
Float, Double: Pour les nombres à virgule flottante
Boolean: Pour les booléens
Character: Pour les caractères
Utilisations courantes
Autoboxing et unboxing: Conversion automatique entre types primitifs et leurs classes d’enveloppement.
Méthodes statiques: Pour accéder à des constantes ou effectuer des conversions.
Collections: Les collections en Java ne peuvent contenir que des objets.
Exemple
int age =30;Integer ageObj = age;// Autoboxingint agePrimitive = ageObj;// UnboxingSystem.out.println(Integer.MAX_VALUE);// Utilisation d'une constante
Expressions, Instructions et Blocs en Java
Expression
Combinaison de variables, opérateurs et appels de méthode
Évalue à une valeur unique
Exemples : x + 5, Math.sqrt(9), a == b
Instruction
Unité exécutable
Types :
Affectation : x = 5;
Appel de méthode : System.out.println("Hello");
Déclaration : int age = 30;
Structure de contrôle : if, for, while, etc.
Créée à partir d’une expression en ajoutant un ;
Blocs
Bloc
Groupe d’instructions délimité par {}
Utilisations :
Corps de méthodes
Corps de structures de contrôle
Délimiter la portée des variables
Exemple
int x =10;// Déclaration et affectationif(x >5){// Bloc ifSystem.out.println("x est supérieur à 5");// Instruction dans le bloc}
Branchements : Instruction switch
Fonctionnalité: Exécute différents blocs de code en fonction de la valeur d’une expression.
Types de valeurs: Entiers, chaînes de caractères, énumérations
Java 14: Le switch a été amélioré en Java 14, permettant une syntaxe plus concise et des fonctionnalités supplémentaires.
switch(expression){case valeur1:// Instructions à exécuter si expression == valeur1break;case valeur2:// Instructions à exécuter si expression == valeur2break;default:// Instructions à exécuter si aucune correspondance}
Exemple
// Utilisation avec une énumérationpublicenum Jour { LUNDI, MARDI, MERCREDI, JEUDI, VENDREDI, SAMEDI, DIMANCHE }Jour j = Jour.SAMEDI;switch(j){case LUNDI, MARDI, MERCREDI, JEUDI, VENDREDI:System.out.println("Jour de semaine.");break;case SAMEDI, DIMANCHE:System.out.println("Jour de fin de semaine.");break;default:System.out.println("Un nouveau jour ?");}
// Utilisation avec une chaîne de caractèresString j ="Samedi";switch(j){case"Lundi","Mardi","Mercredi","Jeudi","Vendredi":System.out.println("Jour de semaine.");break;case"Samedi","Dimanche":System.out.println("Jour de fin de semaine.");break;default:System.out.println("Un nouveau jour ?");}
Pourquoi documenter ? Pour faciliter la compréhension et la maintenance du code.
Comment ? En utilisant des commentaires spécifiques (Javadoc) placés juste avant les éléments à documenter (classes, méthodes, attributs).
Javadoc : l’outil de documentation standard de Java:
Fonctionnement: Javadoc analyse le code source et les commentaires spécifiques pour générer une documentation HTML.
Utilisation: Il est largement utilisé dans l’industrie, notamment par Oracle pour documenter le JDK.
Lien vers la documentation officielle: http://www.oracle.com/technetwork/java/javase/documentation/javadoc-137458.html
Commentaires Javadoc:
Syntaxe: Ils commencent par /** et se terminent par */.
Placement: Ils sont placés juste avant la déclaration de la classe, de la méthode ou de l’attribut à documenter.
Tags: Des tags spécifiques permettent de structurer la documentation (par exemple, @author, @param, @return).
Exemple
/*** Représente un livre.**@author VotreNom*/publicclass Livre {/*** Titre du livre.*/privateString titre;/*** Constructeur de la classe Livre.**@paramtitreLe titre du livre.*/publicLivre(String titre){this.titre= titre;}/*** Retourne le titre du livre.**@return Le titre du livre.*/publicStringgetTitre(){return titre;}}