pdf - e-book - archive - github.com

2.9  Héritage

2.9.1  Héritage

Exercice 1 Point

Définir une classe Point permettant de représenter un point dans R2. Vous utiliserez proprement les concepts d’encapsulation.

Corrigé

Exercice 2 Cercle

Définir une classe Cercle héritant de de la classe précédente. Vous prendrez soin de ne pas recoder des choses déjà codées...

Corrigé

2.9.2  Polymorphisme

Exercice 3 Pile

Adaptez la pile ci-dessous afin qu’elle puisse contenir des objets de n’importe quel type. Vous testerez la pile avec des données de types différents.

package encapsulation.corriges;

public class Pile
{
 /*
  * Tableau contenant les elements de la pile.
  */

 private int[] tab;

 /********************************************/

 /*
  * Taille de la pile
  */

 private final int taille;

 /********************************************/

 /*
  * Indice du premier element non occupe dans le tableau.
  */

 private int firstFree;

 /********************************************/

 /*
  * Constructeur
  */

 Pile(int taille)
 {
  this.taille = taille;
  tab = new int[taille];
  firstFree = 0;
 }

 /********************************************/

 /*
  * Constructeur de copie.
  */

 Pile(Pile other)
 {
  this(other.taille);
  firstFree = other.firstFree;
  for (int i = 0; i < firstFree; i++)
   tab[i] = other.tab[i];
 }

 /********************************************/

 /*
  * Retourne vrai si et seulement si la pile est vide
  */

 public boolean estVide()
 {
  return firstFree == 0;
 }

 /********************************************/

 /*
  * Retourne vrai si et seulement si la pile est pleine.
  */

 public boolean estPleine()
 {
  return firstFree == taille;
 }

 /********************************************/

 /*
  * Retourne l'element se trouvant au sommet de la pile, -1 si la pile est
  * vide.
  */

 public int sommet()
 {
  if (estVide())
   return -1;
  return tab[firstFree - 1];
 }

 /********************************************/

 /*
  * Supprime l'element se trouvant au sommet de la pile, ne fait rien si la
  * pile est vide.
  */

 public void depile()
 {
  if (!estVide())
   firstFree--;
 }

 /********************************************/

 /*
  * Ajoute data en haut de la pile, ne fait rien si la pile est pleine.
  */

 public void empile(int data)
 {
  if (!estPleine())
   tab[firstFree++] = data;
 }

 /********************************************/

 /*
  * Retourne une representation de la pile au format chaine de caracteres.
  */

 public String toString()
 {
  String res = "[";
  for (int i = 0; i < firstFree; i++)
   res += " " + tab[i];
  return res + " ]";
 }

 /********************************************/

 /*
  * Teste le fonctionnement de la pile.
  */

 public static void main(String[] args)
 {
  Pile p = new Pile(30);
  int i = 0;
  while (!p.estPleine())
   p.empile(i++);
  System.out.println(p);
  while (!p.estVide())
  {
   System.out.println(p.sommet());
   p.depile();
  }
 }
}

Télécharger le fichier

Corrigé

Exercice 4 Redéfinition de méthode

Reprenez les classes Point et Cercle, codez une méthode toString() pour les deux classes (mère et fille). Vous prendrez soin d’éviter les redondances dans votre code.

Corrigé

Corrigé

2.9.3  Interfaces

Exercice 5 Animaux

Complétez ce code source, sachant qu’un chien dit "Ouaf !", un chat "Miaou !" et une vache "Meuh !".

package heritage;

import java.util.ArrayList;
@SuppressWarnings("unused")

interface Animal
{
 // Setter pour le champ nom
 public void setNom(String nom);

 // Getter pour le champ nom
 public String getNom();

 // Retourne le cri de l'animal
 public String cri();
}

//TODO Décommentez le code ci-dessous pour le compléter

public class ExempleAnimaux
{
// public static void main(String[] args)
// {
//  ArrayList<Animal> animaux = new ArrayList<>();
//  animaux.add(new Chat("Ronron"));
//  animaux.add(new Chien("Médor"));
//  animaux.add(new Vache("Huguette"));
//  for (Animal animal : animaux)
//   System.out.println("Je m'appelle " + animal.getNom()
//    + " et je dis " + animal.cri() + "!");
// }
}

//class Chat implements Animal
//{
//}
//
//class Chien implements Animal
//{
//}
//
//class Vache implements Animal
//{
//}

Télécharger le fichier

N’hésitez pas à en ajouter d’autres !

Corrigé

Exercice 6 Tab

Reprenez la classe TableauInt et adaptez-là de sorte qu’on puisse y placer tout objet dont le type implémente l’interface Comparable ci-dessous.

package heritage;

import java.util.ArrayList;
import java.util.Random;

public class TableauInt
{
 private ArrayList<Integer> t;

 public TableauInt()
 {
  t = new ArrayList<>();
 }

 public TableauInt(TableauInt other)
 {
  t = new ArrayList<>();
  for (int i = 0 ; i < other.taille() ; i++)
   t.add(other.get(i));
 }

 public int taille()
 {
  return t.size();
 }

 public TableauInt copie()
 {
  return new TableauInt(this);
 }

 public String toString()
 {
  String res = "[";
  if (taille() >= 1)
   res += get(0);
  for (int i = 1 ; i < taille() ; i++)
   res += ", " + get(i);
  res += "]";
  return res;
 }

 public int get(int index)
 {
  return t.get(index);
 }

 public void set(int index, int value)
 {
  int n = taille();
  if (index < n)
   t.set(index, value);
  if (index == n)
   t.add(value);
  if (index > n)
   System.out.println("Achtung !");
 }

 public void echange(int i, int j)
 {
  int temp = get(i);
  set(i, get(j));
  set(j, temp);
 }

 public void triSelection()
 {
  for (int i = 0 ; i < taille() - 1 ; i++)
  {
   int indiceMin = i;
   for (int j = i + 1 ; j < taille() ; j++)
    if (get(indiceMin) > get(j))
     indiceMin = j;
   echange(i, indiceMin);
  }
 }

 public static void main(String[] args)
 {
  int n = 10 ;
  Random r = new Random();
  TableauInt tab = new TableauInt();
  for (int i = 0; i < n; i++)
   tab.set(i, r.nextInt() % 100);
  System.out.println(tab);
  tab.triSelection();
  System.out.println(tab);
 } 
}

Télécharger le fichier

package heritage;

public interface Comparable
{
 /*
  * Retourne un nombre négatif si l'objet courant est plus petit que other,
  * 0 s'ils sont égaux, et un nombre positif l'objet courant est plus grand
  * que other.
  */

 public int compareTo(Comparable other);
}

Télécharger le fichier

Testez TableauInt avec Heure implements Comparable :

package heritage;

import java.util.Random;

public class Heure
{
 private int heures, minutes;

 public Heure(int heures, int minutes)
 {
  this.heures = intAbs(heures) % 24;
  this.minutes = intAbs(minutes) % 60;
 }

 public Heure(Random r)
 {
  this(r.nextInt(), r.nextInt());
 }

 private int intAbs(int x)
 {
  if (x > 0)
   return x;
  else
   return -x;
 }

 public int getHeures()
 {
  return heures;
 }

 public int getMinutes()
 {
  return minutes;
 }

 public void setHeures(int heures)
 {
  this.heures = heures;
 }

 public void setMinutes(int minutes)
 {
  this.minutes = minutes;
 }

 @Override
 public String toString() 
 {
  return heures + ":" + minutes;
 }
 
 public int enMinutes()
 {
  return 60 * heures + minutes;
 }
}

Télécharger le fichier

Corrigé

Corrigé

2.9.4  Classes abstraites

Exercice 7 Animaux

Reprenez le tp sur les animaux, et faites remonter les méthodes setNom et getNom dans la classe mère.

Corrigé

Exercice 8 Classes abstraites et interfaces

Modifier les classes Devise et Animaux pour qu’elles implémentent l’interface Comparable.

Exercice 9 Tri

Tester ComparableTab avec des objets de type Devise et Animaux.

Corrigé

2.9.5  Un dernier casse-tête

Exercice 10 Arbres syntaxiques

Complétez le code source suivant. Il représente un arbre syntaxique.

package heritage;

/**
 * Fonction d'une variable.
 */

public abstract class Function
{
 /**
  * Retourne l'image de x.
  */
 public abstract double evaluate(double x);

 /**
  * Retourne la d&eacute;riv&eacute;e.
  */
 public abstract Function derivate();

 /**
  * Retourne la fonction simplifi&eacute;e.
  */
 public abstract Function simplify();

 /**
  * Ssi la fonction ne contient pas de variable.
  */
 public abstract boolean isConstant();

 /**
  * Ssi la fonction est une feuille valant 0.
  */
 public abstract boolean isZero();

 /**
  * Ssi la fonction est une feuille valant 1.
  */
 public abstract boolean isOne();

 /**
  * Retourne l'integrale entre a et b (a < b), calcul&eacute;e avec la
  * m&eacute;thode des trap&egrave;zes en effectuant nbSubdivisions
  * subdivisions de l'intervalle &agrave; int&eacute;grer.
  */
 public double integrate(double a, double b, int nbSubdivisions)
 {
  return 0;
 }

 public static void main(String args[])
 {
  System.out.println("Hello world !");
 }
}

/**
 * f(x) = x.
 */

class Variable extends Function
{
 Variable()
 {
 }

 @Override
 public boolean isZero()
 {
  // TODO à compléter
  return true;
 }

 @Override
 public boolean isOne()
 {
  // TODO à compléter
  return true;
 }

 @Override
 public boolean isConstant()
 {
  // TODO à compléter
  return true;
 }

 @Override
 public Function derivate()
 {
  return null;
 }

 @Override
 public double evaluate(double x)
 {
  return 0;
 }

 @Override
 public Function simplify()
 {
  return null;
 }

 @Override
 public String toString()
 {
  return "";
 }
}

/**
 * Fonction s'exprimant comme une op&eacute;ration binaire entre deux autres
 * fonctions.
 */

abstract class BinaryOperator extends Function
{
 protected Function leftSon;
 protected Function rightSon;

 BinaryOperator(Function leftSon, Function rightSon)
 {
 }

 /**
  * Retourne l'op&eacute;rateur binaire sous forme de caract&egrave;re ('+'
  * pour une addition '-' pour une soustraction, etc).
  */
 public abstract char toChar();

 @Override
 public String toString()
 {
  return "(" + leftSon + " " + toChar() + " " + rightSon + ")";
 }

 @Override
 public boolean isZero()
 {
  // TODO à compléter !
  return true;
 }

 @Override
 public boolean isOne()
 {
  // TODO à compléter !
  return true;
 }

 @Override
 public boolean isConstant()
 {
  // TODO à compléter !
  return true;
 }

 /**
  * Remplace les sous-arbres par leurs versions simplifi&eacute;es, retourne
  * une feuille si l'arbre est constant.
  */
 protected Function simplifySubTrees()
 {
  return null;
 }

}

/**
 * f(x) = c, o&ugrave; c est une constante r&eacute;elle.
 */

class Constant extends Function
{
 private double value;

 Constant(double value)
 {
 }

 @Override
 public boolean isZero()
 {
  // TODO à compléter
  return true;
 }

 @Override
 public boolean isOne()
 {
  // TODO à compléter
  return true;
 }

 @Override
 public boolean isConstant()
 {
  // TODO à compléter
  return true;
 }

 @Override
 public Function derivate()
 {
  // TODO à compléter
  return null;
 }

 @Override
 public double evaluate(double x)
 {
  // TODO à compléter
  return 0;
 }

 @Override
 public Function simplify()
 {
  // TODO à compléter
  return null;
 }

 @Override
 public String toString()
 {
  // TODO à compléter
  return "";
 }
}

/**
 * f(x) = g(x) - h(x), o&ugrave; g et h sont les sous-arbres gauche et droit.
 */

class Minus extends BinaryOperator
{
 Minus(Function leftSon, Function rightSon)
 {
  super(leftSon, rightSon);
 }

 @Override
 public char toChar()
 {
  // TODO à compléter
  return '?';
 }

 @Override
 public double evaluate(double x)
 {
  // TODO à compléter
  return 0;
 }

 @Override
 public Function derivate()
 {
  // TODO à compléter
  return null;
 }

 @Override
 public Function simplify()
 {
  // TODO à compléter
  return null;
 }
}

/**
 * f(x) = g(x) + h(x), o&ugrave; g et h sont les sous-arbres gauche et droit.
 */

class Plus extends BinaryOperator
{
 Plus(Function leftSon, Function rightSon)
 {
  super(leftSon, rightSon);
 }

 @Override
 public char toChar()
 {
  // TODO à compléter
  return '?';
 }

 @Override
 public double evaluate(double x)
 {
  // TODO à compléter
  return 0;
 }

 @Override
 public Function derivate()
 {
  // TODO à compléter
  return null;
 }

 @Override
 public Function simplify()
 {
  // TODO à compléter
  return null;
 }
}

/**
 * f(x) = g(x) * h(x), o&ugrave; g et h sont les sous-arbres gauche et droit.
 */

class Times extends BinaryOperator
{
 Times(Function leftSon, Function rightSon)
 {
  super(leftSon, rightSon);
 }

 @Override
 public char toChar()
 {
  // TODO à compléter
  return '?';
 }

 @Override
 public double evaluate(double x)
 {
  // TODO à compléter
  return 0;
 }

 @Override
 public Function derivate()
 {
  // TODO à compléter
  return null;
 }

 @Override
 public Function simplify()
 {
  // TODO à compléter
  return null;
 }
}

/**
 * f(x) = g(x) / h(x), o&ugrave; g et h sont les sous-arbres gauche et droit.
 */

class Div extends BinaryOperator
{
 Div(Function leftSon, Function rightSon)
 {
  super(leftSon, rightSon);
 }

 @Override
 public char toChar()
 {
  // TODO à compléter
  return '?';
 }

 @Override
 public double evaluate(double x)
 {
  // TODO à compléter
  return 0;
 }

 @Override
 public Function derivate()
 {
  // TODO à compléter
  return null;
 }

 @Override
 public Function simplify()
 {
  // TODO à compléter
  return null;
 }
}

Télécharger le fichier

Corrigé