Table des matières

TD 4 - Classes abstraites et accès protégé

Lors du TP3, nous avons vu la notion d’héritage et nous avons fait en sorte que toutes les figures géométriques manipulées soient les filles d’une classe commune Shape2D.

Peut-être avez-vous remarqué que la classe Shape2D ne contenait pas de code qui puisse être appelé. Cette classe Shape2D reste néanmoins utile puisqu’elle nous permet par exemple des créer un table de Shape2D, où chaque élément peut être de type différent à condition d’hériter de Shape2D.

Dans un tel cas de figure, c’est-à-dire quand une classe sert d’intermédiaire pour introduire des méthodes qui seront définies dans ses classes-filles, on définit cette classe en classe abstraite.

Une classe abstraite se déclare comme suit :

public abstract class MyAbstractClass {
...
}

Notez qu’on ne peut pas instancier de variables de type d’une classe abstraite. Par exemple, ça n’aurait pas de sens de créer une variable de type Shape2D :

  Shape2D s = new Shape2D();  // impossible if Shape2D is an abstract class

est impossible si Shape2D est définie en classe abstraite. En revanche, on peut mettre une instance d’une classe-fille dans une variable du type de la classe abstraite, par exemple :

  Triangle t = new Triangle( ... );
  Shape2D s = t; 

Une classe abstraite peut également disposer de méthodes abstraites, c’est-à-dire de méthodes dont on spécifie uniquement le nom et les arguments, mais que l’on n’implémente pas. Chaque classe fille non-abstraite devra alors implémenter sa version de cette méthode.

Une méthode abstraite se déclare comme suit :

public abstract Type MyMethod (T1 argument1, T2 argument2);

Une classe abstraite peut cependant également disposer de champs et de méthodes habituelles, c’est-à-dire dont on définit le code.

Abstraction de Shape2D

Nous nous baserons sur le code réalisé au TP3.

Organisation du code

Pour régler ce problème, il va falloir organiser un peu le dossier de travail de manière à ce que vos fichiers soient regroupés par package.

protected

Nous avons maintenant beaucoup de classes dans le dossier shape et on souhaite maintenant les séparer en plusieurs sous-dossiers.

Sans modificateur d’accès, un attribut n’est visible que dans le dossier (qu’on appelle package en Java) où se trouve sa classe. Cependant, on ne veut pas non plus mettre name en public puisqu’on ne veut pas qu’il soit visible à l’extérieur d’un objet de type Shape2D. Il existe heureusement un modificateur d’accès, protected qui permet qu’un attribut soit visible uniquement par le package ET par les sous-classes de l’objet dans lequel il se trouve.

Égalité

On peut parfois souhaiter vérifier si on manipule deux figures identiques. Ajoutez le code suivant à TestShape2D:

  Point2D D = new Point2D(1.0, 1.0);
  Point2D E = new Point2D(1.0, 1.0);
  if (D == E) {
    System.out.println("Les points sont égaux");
  }

Ce comportement est dû au fait qu’en java l’égalité == compare les références des objets et non leurs valeurs. Une méthode de la classe Object appelée equals est chargée de comparer les valeurs.

En réalité, la méthode equals de Object est très générale et ne peut comparer directement que des valeurs numériques, il faut donc redéfinir cette méthode dans vos classes, en testant quand les valeurs de deux objets sont égales.

public boolean equals(Object o)

Vous veuillerez à vérifier que l’objet passé en argument est instancié (c’est-à-dire que sa référence n’est pas null) et que c’est bien un objet de la classe correspondante. Cette classe vous est renvoyée par la méthode getClass(). Vous pouvez également déterminer si o est un point grâce à l’opérateur instanceof de la manière suivante : o instanceof Point2D.

Classe Polygone

Remarquez que la classe Polygone, créée à la fin du TD3, devrait également être une classe abstraite. Changez donc cette classe (et ses méthodes) en abstract.

Superposition de figures

Pour la création des fichiers SVG, nous souhaitons pouvoir définier comment les formes se superposent les unes par rapport aux autres. Ajoutez une propriété zIndex de type entier à chaque type de figure. La valeur zIndex doit être comprise entre 0 et 100.

Inclusion de point dans une forme