US

La classe Object

Hiérarchie de classes

Une sous-classe qui est dérivée d'une superclasse peut elle même avoir une sous-classe. De cette manière, on construit ce que l'on appelle une hiérarchie de classes. Un exemple typique d'hiéarchie de classes se base sur le monde animal et est illustré sur la figure suivante.

Hiérarchie de classes
fig j9.6 Hiérarchie de classes

Il n'y a pas de limite quant au nombre d'enfants que peut avoir une classe ou quant au nombre de niveaux qu'une hiérarchie de classe peut avoir. Une classe peut donc avoir une classe parent, une classe grand-parent, ... En général, on parlera des ancêtres d'une classe. Une classe hérite donc des éléments de tous ses ancêtres.

Il existe encore une autre relation particulière entres deux classes, enfants d'un même parent. En anglais, il existe un mot pour qualifier cette relation, on dit que les deux classes sont siblings. Il n'existe pas de mot en français, on dit simplement que les deux classes ont le même parent. Ce genre de classes ont la particularité d'hériter des mêmes éléments, tandis que chacune d'entre elles va se spécialiser.

Général et spécifique

Pour rappel, une superclasse est toujours plus générale qu'une sous-classe, ainsi, dans une hiérarchie de classes, les caractéristiques communes à tout le monde se trouveront dans les classes les plus hautes tandis que les caractéristiques spécifiques se retrouveront dans les classes du bas de la hiérarchie.

Enfin, il faut savoir que la relation d'héritage est transitive, c'est-à-dire que tout ce qu'une classe a hérité de sa superclasse, elle va le léguer à propres ses sous-classes. Ainsi, un membre hérité peut se trouver dans la superclasse, ou plus haut dans la hiérarchie, dans un des ancêtres.

Hiéarchie d'interfaces

Le concept d'héritage s'applique également aux interfaces, ainsi, une interface peut en étendre une autre. Une classe qui implémente une telle interface devra donc implémenter toutes les méthodes de l'interface ainsi que de la superinterface, etc ...

On peut donc construire des hiérarchies d'interfaces. Il est néanmoins interdit de mélanger classes et interfaces, une classe n'étend pas une interface et une interface n'étend pas une classe.

Classes et interfaces
fig j9.7 Classes et interfaces

La figure précédent illustre un schéma que l'on retrouve assez souvent. On a tout d'abord une interface Interface1 qui est implémentée par la classe Classe1. Classe1 implémente donc toutes les méthodes qui sont dans l'interface Interface1.

Ensuite, on décide d'étendre l'interface Interface1, de lui ajouter des méthodes, mais pour le faire de manière « propre », c'est-à-dire en respectant la programmation orientée objet, on crée une nouvelle interface Interface2 qui étend Interface1. On ajoute les méthodes supplémentaires dans Interface2.

Si on veut écrire une classe qui implémente Interface2, elle devra contenir une implémentation pour toutes les méthodes de Interface1 et Interface2, la solution offerte par la programmation orientée objet est de repartir de Classe1 qui contient déjà une implémentation pour toutes les méthodes de Interface1, on crée une nouvelle classe Classe2 qui étend Classe1 et on y ajoute une implémentation des méthodes de Interface2.

La classe Object

En Java, toute classe qui n'étend pas une autre en utilisant le mot réservé extends étend implicitement la classe Object (qui se trouve dans le package java.lang). Ainsi, toutes les classes Java ont comme premier ancêtre la classe Object.

Les méthodes de la classe Object

Étant donné que toutes les classes étendent la classe Object (directement ou indirectement), tout objet à accès aux méthodes publiques définies dans la classe Object. Certaines des méthodes de cette classe sont très intéressantes et méritent notre attention.

On a déjà rencontré quelques-unes de ces méthodes tout au long de ce tutoriel Java, on conseillait par exemple d'ajouter à toutes les classes une méthode toString, une méthode equals, ... Jusqu'à présent, on ne savait pas trop pourquoi ces méthodes devaient posséder une telle signature, et bien maintenant, on comprends qu'il s'agit simplement d'une surcharge des méthodes se trouvant dans la classe Object.

  1. public String toString();

    Cette méthode permet d'obtenir une représentation de l'objet sous forme d'une chaine de caractère.

  2. public boolean equals (Object o);

    Cette méthode permet de comparer un objet à l'objet courant pour savoir s'ils sont égaux ou non.

  3. protected Object clone();

    Cette méthode permet d'obtenir une copie de l'objet et non pas une copie de la référence vers l'objet.

La classe Object rassemble donc des méthodes que tout objet aura étant donné que toutes les classes héritent directement ou indirectement de la classe Object. Cette classe se trouvant tout en haut de la hiérarchie de classes possède donc des méthodes très générales comme nous venons de les voir.

Spécialisation des méthodes de la classe Object

Il est néanmoins possible de spécialiser le comportement de ces méthodes pour une classe particulière en utilisant le mécanisme de surcharge de méthode rencontré à la section précédente. Nous allons voir un exemple.

Voici une classe qui représente un livre. Dans notre exemple, un livre ne possède qu'un titre ainsi qu'une liste d'auteurs. On va donc utiliser deux variables d'instances : la première est un tableau de String pour les auteurs et la seconde un String pour le titre.