Table des matières

TD 2 - Prise en main d’un IDE adapté

Code non encapsulé

Nous allons partir du code commun suivant de la classe Point2D

class Point2D {
	double x, y;

	Point2D() {
		// ne fait rien
	}

	Point2D(double x, double y) {
		this.x = x;
		this.y = y;
	}

	void afficher() {
		System.out.println("Point : (" + x + ", " + y + ")");
	}

	void deplacement(double dx, double dy) {
		x += dx;
		y += dy;
	}

	void deplacement(double delta) {
		deplacement(delta, delta);
	}

	double distance(Point2D p) {
		double d1 = p.x - x;
		double d2 = p.y - y;
		return Math.sqrt(d1*d1 + d2*d2);
	}
}

et la classe de test TestPoint2D

class TestPoint2D {

	public static void main(String[] args) {
		Point2D p1, p2;

		p1 = new Point2D(0, 0);
		p1.afficher();

		p2 = new Point2D(0, 3);
		p2.afficher();

		System.out.println("Distance = " + p2.distance(p1));

		p1.deplacement(1,1);
		p1.afficher();

		p2.deplacement(1);
		p2.afficher();

		System.out.println("Distance = " + p2.distance(p1));

	}

}

Mondialisation

La première chose à effectuer est de respecter les standards de codage qui recommandent d’utiliser l’anglais pour permettre au plus grand nombre une relecture aisée du code.

Par la suite, n’oubliez pas de directement écrire vos classes en anglais.

Problèmes d’encapsulation “simples”

Comme vous pouvez le constater en modifiant la fonction main, il est possible d’accéder directement aux attributs de la classe Point2D en lecture et modification. Or l’utilisateur d’une classe n’a pas à connaître la structuration des données d’un objet. En interdisant toute modification directe des attributs, et en obligeant l’utilisateur à utiliser des fonctions pré-définies pour les modifier (appelées getter/setter), il est possible de garantir l’intégrité des données mais aussi de permettre une plus grande souplesse sur les changements de structuration des données.

Si l’on souhaite pouvoir modifier les coordonnées du point, il faut éventuellement des fonctions spécifiques appelées setter (i.e. void setX(double x) et void setY(double y)). A noter que ces dernières ne sont pas toujours utiles s’il existe déjà des méthodes permettant de modifier les attributs.

L’utilisation de la méthode de déplacement permet de modifier les champs mais n’est pas vraiment pratique car elle nécessite d’effectuer une translation relative à la position actuelle. Il est également possible d’utiliser le constructeur qui va provoquer la création d’un nouveau point. Le point qui existait sera détruit automatiquement par le garbage collector. Cette solution est acceptable mais consomme inutilement un peu de mémoire le temps que le garbage collector effectue son travail. Ajoutez donc les setters.

Modificateurs de méthodes

Actuellement, nos méthodes n’ont pas de modificateurs d’accès. L’absence de modificateurs d’accès est en soit un niveau de visibilité, appelé friendly et qui correspond à la visibilité paquetage. Nous aborderons ces notions plus tard, mais pour faire simple, toutes les classes d’un même répertoire appartiennent au même paquetage. Cependant, il est courant que l’on souhaite rendre disponibles le plus largement possible certaines méthodes. On utilise dans ce cas le modificateur d’accès public.

Problèmes d’encapsulation plus complexes

Repartez du code des classes Cercle et TestCercle suivant et modifiez le pour prendre en compte l’ensemble de ce que vous avez vu précédemment.

class Cercle {
	Point2D centre;
	double rayon;

	Cercle (Point2D centre, double rayon) {
		this.centre = centre;
		this.rayon = rayon;
	}

	double surface() {
		return Math.PI * rayon*rayon;
	}

	boolean estInterieur(Point2D p) {
		double distance = p.distance(centre);
		return distance <= rayon;
	}
}

class TestCercle {
	public static void main(String[] args) {
		Point2D  p = new Point2D(2,3);
		Point2D  centre = new Point2D(1,1);
		Cercle c = new Cercle(centre, 4);
		System.out.println("Surface = " + c.surface());
		System.out.println("Interieur : " + c.estInterieur(p));
	}
}

Et pourtant, les attributs de la classe sont maintenant privés (private) … Si vous avez modifié votre code comme convenu, vous devriez également avoir des getters.

Autres figures géométriques

Remarque : La surface d’un triangle quelconque se fait à partir des longueurs a, b et c de chacun de ses côté gràce à la formule suivante :

Pour aller plus loin

Nous utiliserons dans le cadre du projet la bibliothèque JavaFX pour gérer l’affichage graphique. Plutôt que de faire un export SVG, nous pourrions directement dessiner les former manipulées. Vous pouvez consulter en ligne la documentation sur l’utilisation de JavaFX.