DESS CCI
TD de Programmation Orientée Objet n°2

Corrigé

par Philippe.Genoud@imag.fr.

 

Thème 1 : expressions / instructions conditionnelles

Exercice 1 : Conversion de températures
     
/**
 * Degres.java
 *
 * lit une température exprimée en degrés Fahrenheit et affiche sa valeur en degrés Celsius. 
 *
 * Created: Sat Jan 05 14:07:09 2002
 *
 * @author <a href="mailto:Philippe.Genoud@imag.fr">Philippe Genoud</a>
 * @version
 */

public class Degres {

    public static void main(String[] args)
    {
	double tempF;
        System.out.print("entrez une température (en °F) : ");
        tempF = LectureClavier.lireDouble();
	
	double tempC = (5.0/9.0)*(tempF-32);  // attention ! : il faut bien écrire 5.0/9.0
	                                      // et non pas 5/9 car sinon on effectue une
	                                      // division entière et le résultat de l'expression
	                                      // est alors toujours égal à 0

	System.out.println("cette température équivaut à °C : " + tempC);
    }
    
} //Degres

télécharger le source java

Exercice 2 : Conversion de durées

 
     
/**
 * Hjms.java
 *
 * Lit au clavier une durée exprimée en seconde et la convertit
 * en nombre de jour, heures, minutes et secondes.
 *
 * Created: Wed Feb  3 10:53:53 1999
 *
 * @author Philippe Genoud (Philippe.Genoud@imag.fr)
 * @version
 */

public class Hjms  {

    public static void main(String[] args)
    {

	int duree;
        System.out.print("entrez une durée (en sec.) : ");
        duree = LectureClavier.lireEntier();
        
        int nbJours = duree / (24 * 60 * 60);  //l'opérateur '/' est l'opérateur de division entière
        duree = duree % (24 * 60 * 60);        //l'opérateur '%' est l'opérateur modulo, reste de la
	                                       //division entière
        
        int nbHeures = duree / (3600);
        duree = duree % 3600;
        
        int nbMin = duree / 60;
        
        int nbSec = duree % 60;

        System.out.println("Cette duree equivaut a ");
        System.out.println(nbJours + " jours " + nbHeures + " heures " +
                   nbMin + " minutes " + nbSec + "secondes");

    }
    
} // Hjms

télécharger le source java

Exercice 3 : Déterminer de l'appartenance d'un point à une couronne

 
/**
 * Couronne.java
 *
 * Created: Sat Jan 05 14:14:38 2002
 *
 * détermine si un point P du plan se trouve ou non à l'intérieur de la couronne de 
 * centre l'origine et définie par la donnée de son rayon extérieur r1 et de son 
 * rayon intérieur r2.
 *
 * @author <a href="mailto:Philippe.Genoud@imag.fr">Philippe Genoud</a>
 * @version
 */

public class Couronne {

    public static void main(String[] args)
    {
      double r1; // rayon intérieur de la couronne
      double r2; // rayon extérieur de la couronne

      System.out.print("entrez le rayon intérieur de la couronne : ");
      r1 = LectureClavier.lireDouble();

      System.out.print("entrez le rayon extérieur de la couronne : ");
      r2 = LectureClavier.lireDouble();

      double x,y; // les coordonnées du point

      System.out.print("entrez l'abscisse du point : ");
      x = LectureClavier.lireDouble();
      System.out.print("entrez l'ordonnée du point : ");
      y = LectureClavier.lireDouble();
      
      double dist = (x * x) + (y * y);  // le carre de la distance à l'origine

      if ( (dist >= r1*r1) && (dist <= r2*r2))
	    System.out.println("Le point est dans la couronne");
      else
	    System.out.println("Le point n'est pas dans la couronne");

  }

} // Couronne

télécharger le source java

Thème 2 : Itérations

Exercice 1 : Calcul de X^n

a)

 
     
/**
 * Puissance1.java
 *
 * calcule et affiche la valeur de x^n (lire x puissance n) 
 * où x et n sont respectivement un réel et un entier introduits au clavier. 
 *
 * Created: Sat Jan 05 14:28:55 2002
 *
 * @author <a href="mailto:Philippe.Genoud@imag.fr">Philippe Genoud</a>
 * @version
 */

public class Puissance1 {

  public static void main(String[] args)
    {
      int n;
      double x;
      double res;

      System.out.print("rentrez la puissance : ");
      n = LectureClavier.lireEntier();

      System.out.print("rentrez x : ");
      x = LectureClavier.lireDouble();

      System.out.print(x + " puissance " + n + " = ");
    
      if (n == 0)
       	if (x >= 0)
	          System.out.println("1");
       	else
	          System.out.println("Pas défini");
      else // n != 0
       	if (n > 0) {
	           res = 1;
	           for (int i = 0; i < n; i++)
	              res = res * x;
	           System.out.println(res);
       	}
       	else // n < 0
	          if (x == 0) 
	             System.out.println("Pas défini");
	          else {
	             res = 1;
	             for (int i = n; i < 0; i++)
	               res = res * x;
	             System.out.println(1/res);
	          }
    } // main

} // Puissance1

télécharger le source java

b)

 

     
/**
 * Puissance2.java
 *
 * calcule et affiche la valeur de x^n (lire x puissance n) 
 * où x et n sont respectivement un réel et un entier introduits au clavier. 
 * après chaque calcul de puissance le programme demande à l'utilisateur si il veut
 * faire un autre calcul ou non. 
 *
 * Created: Sat Jan 05 14:28:55 2002
 *
 * @author <a href="mailto:Philippe.Genoud@imag.fr">Philippe Genoud</a>
 * @version
 */

public class Puissance2 {

  public static void main(String[] args)
    {
      int n;
      double x;
      double res;

      boolean encore;

      do {

 	      System.out.print("rentrez la puissance : ");
	      n = LectureClavier.lireEntier();

	      System.out.print("rentrez x : ");
         x = LectureClavier.lireDouble();

         System.out.print(x + " puissance " + n + " = ");
    
         if (n == 0)
            if (x >= 0)
               System.out.println("1");
            else
	            System.out.println("Pas défini");
         else // n != 0
	         if (n > 0) {
	            res = 1;
	            for (int i = 0; i < n; i++)
	                res = res * x;
	            System.out.println(res);
	          }
	          else // n < 0
	              if (x == 0) 
	                   System.out.println("Pas défini");
	             else {
	               res = 1;
                  for (int i = n; i < 0; i++)
                     res = res * x;
	               System.out.println(1/res);
	             }

        System.out.print("encore O/N ? ");
        encore = LectureClavier.lireOuiNon();
      } while (encore);
    }

} // Puissance2

télécharger le source java

Exercice 2 : Valeur approchée de la racine carrée d'un nombre réel positif

a)

 
     
/**
 * Raca1.java
 *
 *  Calcule la racine carrée d'un nombre réel posiitf.
 *
 *  Pour cela on calcule la suite (un) n=0,1,2,... définie par la donnée d'un réel u0 positif et
 *  par la relation de récurrence un = (un-1 + A / un-1) * 0,5 (pour n > 0) qui converge vers la
 *  racine carrée de A.
 *
 * On suppose le nombre A compris entre 1 et 100, et on prend u0 = A / 2. 
 *
 * Created: Sat Jan 05 14:53:09 2002
 *
 * @author <a href="mailto:Philippe.Genoud@imag.fr">Philippe Genoud</a>
 * @version
 */

public class Raca1 {

  public static final double EPS = 1E-5;

  public static void main(String[] args)
    {
      double a;

      System.out.println("entrez un réel : ");
      a = LectureClavier.lireDouble();


      double UiMoins1 = a / 2;                      // u0
      System.out.println("u0 " + UiMoins1);

      int i = 1;
      double Ui = 0.5 * (UiMoins1 + a / UiMoins1);  // u1

      while ( Math.abs(Ui*Ui - a) >= EPS) {
	       System.out.println("u" + i + " " + Ui);
	       i++;
	       UiMoins1 = Ui;
          Ui = 0.5 * (UiMoins1 + a / UiMoins1);
      }

      System.out.println("Valeur approchée de la racine carrée de " + a + 
                 " : u" + i + " " + Ui);
	  
  }
  
}// Raca1

télécharger le source java

b)

 
     
/**
 * Raca1.java
 *
 *  Calcule la racine carrée d'un nombre réel posiitf.
 *
 *  Pour cela on calcule la suite (un) n=0,1,2,... définie par la donnée d'un réel u0 positif et
 *  par la relation de récurrence un = (un-1 + A / un-1) * 0,5 (pour n > 0) qui converge vers la
 *  racine carrée de A.
 *
 * On suppose le nombre A compris entre 1 et 100, et on prend u0 = A / 2. 
 *
 * Le programme vérifie que le nombre introduit est bien dans l'intervalle 0/100; 
 *
 * Created: Sat Jan 05 14:53:09 2002
 *
 * @author <a href="mailto:Philippe.Genoud@imag.fr">Philippe Genoud</a>
 * @version
 */

public class Raca2 {

  public static final double EPS = 1E-5;

  public static void main(String[] args)
    {
      double a;

      System.out.print("entrez un réel (>= 1 et <= 100): ");
      a = LectureClavier.lireDouble();
      while ( (a < 1) || ( a > 100) ) {
        System.out.println("valeur incorrecte ");
        System.out.print("entrez un réel (>= 1 et <= 100): ");
        a = LectureClavier.lireDouble();
      }

      double UiMoins1 = a / 2;                      // u0
      System.out.println("u0 " + UiMoins1);

      int i = 1;
      double Ui = 0.5 * (UiMoins1 + a / UiMoins1);  // u1

      while ( Math.abs(Ui*Ui - a) >= EPS) {
	      System.out.println("u" + i + " " + Ui);
	      i++;
	      UiMoins1 = Ui;
         Ui = 0.5 * (UiMoins1 + a / UiMoins1);
      }

      System.out.println("Valeur approchée de la racine carrée de " + a + 
                 " : u" + i + " " + Ui);
	  
  }
  
}// Raca2

télécharger le source java

Thème 3 : Instanciation d'objets, envois de messages

Ecrivez une application donnant aux visages qui se déplacent dans la fenêtre graphique une trajectoire moins répétitive. Au lieu de se déplacer uniquement selon une diagonale, les visages se déplacent selon les quatre directions Nord-Ouest -> Sud-Est, Sud-Ouest -> Nord-Est, Sud-Est -> Nord-Ouest et Nord-Est -> Sud-Ouest. La direction du déplacement d'un visage sera modifiée à chaque rencontre de ce dernier avec un bord de la fenêtre. Si vous avez le temps vous pouvez aussi animer les visages en les dotant d'un changement d'expression à chaque changement de direction.

solution 1

a) modification de la classe VisageRond

b) modification du programme principal

solution 2

On peut ensuite améliorer la solution précédente en factorisant le code de détection des bords et de changement d'expression. Plutôt que de répéter ce code autant de fois qu'il y a de visages on peut ajouter à la classe VisageRond une méthode public void deplacerAvecRebond() qui combine ces traitements et dont le code serait :

    public void deplacerAvecRebond() {
        if (this.bordDroitAtteint() || this.bordGaucheAtteint()) {
           this.inverserDx();
           this.changeExpression();
        }
        if (this.bordHautAtteint() || this.bordBasAtteint()) {
           this.inverserDy();
           this.changeExpression();
        } 
        
        this.deplacer();
    }

du coup, la boucle d'animation du programme principal devient très simple :

      // la boucle d'animation
      while (true)
         {

            // les visages effectuent un déplacement élémentaire
            // en rebondissant sur les bords et en changeant d'expression
            v1.deplacerAvecRebond();
            v2.deplacerAvecRebond();

            // la zone de dessin se réaffiche
            d.repaint();
            
             // un temps de pause pour avoir le temps de voir le nouveau dessin
            d.pause(50);

         } 
télécharger le source java de VisageRond.java et AppliVisage3.java