Sommaire
Introduction à la classe Object en Java
Pfiou, l’héritage en Java, c’est tout un monde ! Vous avez déjà appris les bases avec les mots-clés extends
et super
, comment invoquer les constructeurs et méthodes des classes parentes, et comment les surcharger. Mais il est temps d’explorer la classe mère de toutes les classes Java : java.lang.Object
.
Cette classe, présente dans le package java.lang
, est la superclasse ultime de toutes les autres classes Java. En comprenant son fonctionnement et ses méthodes, vous aurez une vision plus complète de l’héritage dans ce langage de programmation.
Object déclare les méthodes suivantes, que toutes les autres classes héritent : clone(), equals(), finalize(), getClass(), hashCode(), notify(), notifyAll(), toString(), wait(), wait(long timeout) et wait(long timeout, int nanos).
Une classe Java hérite de ces méthodes et peut en surcharger certaines qui ne sont pas déclarées final
. Par exemple, toString()
n’est pas final
et peut donc être surchargée, contrairement aux méthodes wait()
qui sont final
.
Comment étendre la classe Object : un exemple
Voilà, on commence les choses sérieuses ! Une classe peut explicitement étendre Object
, comme dans l’exemple suivant :
public class Employee extends Object { private String name; public Employee(String name) { this.name = name; } public String getName() { return name; } public static void main(String[] args) { Employee emp = new Employee("John Doe"); System.out.println(emp.getName()); // Affiche "John Doe" }}
Cependant, comme Java n’autorise l’héritage que d’une seule classe (pas d’héritage multiple), vous n’êtes pas obligé d’étendre explicitement Object
. Dans ce cas, votre classe l’étendra implicitement, comme ici :
public class Employee { private String name; public Employee(String name) { this.name = name; } public String getName() { return name; } public static void main(String[] args) { Employee emp = new Employee("John Doe"); System.out.println(emp.getName()); // Affiche "John Doe" }}
Que vous l’étendiez explicitement ou non, Object
sera toujours la superclasse de votre classe Employee
.
Les méthodes de la classe Object
Maintenant, plongeons dans les méthodes déclarées par Object
et voyons comment les utiliser dans vos programmes.
getClass()
Cette méthode retourne la classe runtime de l’objet sur lequel elle est appelée. La classe runtime est représentée par un objet Class
, qui est le point d’entrée de l’API de réflexion Java. Cette API permet à une application Java d’examiner sa propre structure.
clone()
La méthode clone()
crée et retourne une copie de l’objet sur lequel elle est appelée. Comme son type de retour est Object
, vous devez caster la référence retournée vers le type de l’objet cloné avant de l’assigner à une variable.
Pour utiliser clone()
, votre classe doit implémenter l’interface Cloneable
afin d’éviter que la méthode ne lève une CloneNotSupportedException
. Voici un exemple :
class CloneDemo implements Cloneable { int x; public static void main(String[] args) throws CloneNotSupportedException { CloneDemo cd = new CloneDemo(); cd.x = 5; System.out.println("cd.x = " + cd.x); // Affiche "cd.x = 5" CloneDemo cd2 = (CloneDemo) cd.clone(); System.out.println("cd2.x = " + cd2.x); // Affiche "cd2.x = 5" }}
Ici, nous avons cloné un objet CloneDemo
en appelant clone()
sur son instance. Comme la méthode retourne un Object
, nous avons dû caster le résultat en CloneDemo
pour l’assigner à cd2
.
Si votre classe contient des champs référençant d’autres objets, vous devrez probablement surcharger clone()
pour implémenter un clonage profond (deep cloning) afin d’éviter ce comportement indésirable.
equals()
La méthode equals(Object obj)
permet de comparer deux objets pour l’égalité. Dans sa forme par défaut, elle compare les références d’objets, retournant true
si les deux références pointent vers le même objet en mémoire.
Cependant, vous voudrez généralement surcharger cette méthode pour implémenter une logique de comparaison plus pertinente pour votre classe. Par exemple, pour une classe représentant une personne, vous pourriez considérer deux instances égales si leur nom et date de naissance sont identiques.
finalize()
La méthode finalize()
est appelée par le ramasse-miettes (garbage collector) de la JVM juste avant qu’un objet ne soit récupéré. Elle est généralement utilisée pour libérer les ressources détenues par l’objet, comme les connexions réseau ou les fichiers ouverts.
Cependant, il est préférable d’utiliser des blocs try/finally
ou la classe AutoCloseable
pour une gestion plus sûre des ressources, car l’appel de finalize()
n’est pas garanti.
hashCode()
Cette méthode retourne un code de hachage (hash code) pour l’objet sur lequel elle est appelée. Ce code est utilisé par les tables de hachage, comme HashMap
, pour stocker et récupérer efficacement les objets.
Si vous surchargez equals()
, vous devez généralement aussi surcharger hashCode()
pour respecter le contrat entre ces deux méthodes. Sinon, les performances des tables de hachage peuvent se dégrader considérablement.
toString()
La méthode toString()
retourne une représentation textuelle de l’objet. Par défaut, elle affiche le nom de la classe suivi de l’adresse mémoire de l’objet, ce qui n’est souvent pas très utile.
C’est pourquoi il est courant de surcharger cette méthode pour retourner une chaîne de caractères plus informative, décrivant l’état de l’objet. Par exemple, pour une classe Employee
, toString()
pourrait retourner le nom et le salaire de l’employé.
wait() et notify()
Ces méthodes sont utilisées pour la synchronisation des threads en Java. wait()
met un thread en attente jusqu’à ce qu’un autre thread appelle notify()
ou notifyAll()
sur le même objet.
Elles sont généralement utilisées dans des blocs synchronized
pour coordonner l’accès à une ressource partagée entre plusieurs threads. Cependant, leur utilisation peut être complexe et sujette à des problèmes de concurrence si elle n’est pas faite avec précaution.
Conclusion : l’utilité de la classe Object dans l’héritage
Vous l’aurez compris, la classe Object
est au cœur de l’héritage en Java. En maîtrisant ses méthodes, vous pourrez écrire des programmes plus robustes et efficaces, tout en tirant pleinement parti de l’héritage pour réutiliser du code existant.
Que vous soyez débutant ou développeur chevronné, n’hésitez pas à explorer davantage les possibilités offertes par cette classe fondamentale. Vous serez surpris de constater à quel point elle peut faciliter votre travail et vous faire gagner un temps précieux.
Le mus-have de la classe Object
- Toutes les classes Java héritent de Object et ses méthodes
- clone() pour dupliquer des objets
- equals() pour comparer des objets
- hashCode() pour les tables de hachage
- toString() pour obtenir une représentation textuelle
- wait() et notify() pour la synchronisation des threads