Test 2 - Lundi 8 juin - 20 minutes
Table of Contents
Nom : …………………….. - Prénom : ………………………
Les réponses sont à donner directement sur l'énoncé, en complétant les espaces libres en pointillé. Pour les questions fermées (à choix simple), cocher la case correspondant à sa réponse.
- Le langage de programmation utilisé est Java (version 7 ou version 8 pour une question).
- Dans la suite, l'expression … (trois points) représente du code supposé connu : elle est suivie d'un commentaire décrivant le code omis.
Considérons l'interface suivante.
interface Fonction { double valeur(double x); }
Un objet f de type Fonction représente une fonction à valeurs réelles, les réels étant représentés par des double : l'image du double x par f est donnée par f.valeur(x).
On s'intéresse à des fonctions ayant un zéro sur un intervalle fermé fixé, par exemple entre 0 et 1.
Compléter la déclaration de l'interface FonctionAvecZero de manière à garantir que tout objet f de type FonctionAvecZero est aussi de type Fonction et possède une méthode double unZero() donnant un point d'annulation de la fonction associée (un x tel que f.valeur(x) vaut 0, à une approximation près).
interface FonctionAvecZero ............................................. { ...................................................................... }
On considère des implémentations de la méthode unZero pouvant s'exprimer en utilisant la seule méthode valeur.
Dichotomie pour polynômes
On suppose que la classe Polynome implémente l'interface Fonction. En déduire par héritage une classe PolynomeAvecZeroParDichotomie implémentant l'interface FonctionAvecZero. On notera DICHOTOMIE le code de la méthode unZero, une implémentation de l'algorithme par dichotomie.
class PolynomeAvecZeroParDichotomie .................................... ...................................................................... { ...................................................................... ...................................................................... ...................................................................... ...................................................................... }
Qualifier correctement l'approche par héritage utilisée pour factoriser ci-dessus la classe d'implémentation Polynome.
\[ \begin{array}{llcll} \Box & \mathrm{ascendante} & \quad \quad & \Box & \mathrm{descendante} \\ \end{array} \]Dichotomie pour séries de Fourier
On souhaite implémenter une nouvelle classe de fonctions correspondant à des séries de Fourier. Peut-on définir par héritage une nouvelle classe SerieFourierAvecZeroParDichotomie
- ne partageant aucun état avec PolynomeAvecZeroParDichotomie,
- implémentant la méthode unZero de l'interface FonctionAvecZero en utilisant l'algorithme par dichotomie mais
- sans répéter le code DICHOTOMIE ?
Quelle approche par héritage permet de factoriser l'implémentation de l'algorithme par dichotomie ?
\[ \begin{array}{llcll} \Box & \mathrm{ascendante} & \quad \quad & \Box & \mathrm{descendante} \\ \end{array} \]Compléter la définition de la classe FonctionAvecZeroParDichotomie de manière à implémenter partiellement l'interface FonctionAvecZero, seule la méthode unZero étant implémentée en utilisant le code DICHOTOMIE.
........................................................................
class FonctionAvecZeroParDichotomie ..................................
....................................................................
{
......................................................................
......................................................................
......................................................................
......................................................................
}
En déduire une définition de la classe SerieFourierAvecZeroParDichotomie. On précisera l'interface la plus précise qu'elle implémente.
class SerieFourierAvecZeroParDichotomie ................................ ...................................................................... ...................................................................... { ... // Attributs et constructeurs @Override public double valeur(double x) { ... // Code calculant la valeur en x } }
Algorithme de Newton
Pour cette question, on utilise Java 8. A partir de cette version de Java, il est possible de définir une implémentation dite par défaut d'une méthode déclarée dans une interface : il suffit de préfixer la définition de la méthode par default. On peut ainsi obtenir un héritage multiple, entre d'une part une classe et d'autre part une interface ayant des méthodes implémentées. On suppose aussi qu'une classe SerieFourier représentant des séries de Fourier implémente l'interface Fonction.
La méthode par dichotomie est bien moins efficace que la méthode de Newton pour la recherche d'un zéro d'une fonction. Pour cette raison, on souhaite définir par héritage respectivement de Polynome et de SerieFourier deux nouvelles classes, PolynomeAvecZeroParNewton et SerieFourierAvecZeroParNewton. Compléter le code suivant en proposant une solution par héritage multiple permettant de factoriser l'implémentation de la méthode unZero par l'algorithme de Newton. On notera NEWTON le code de la méthode unZero.
............................................ FonctionAvecZeroParNewton ..................................................... FonctionAvecZero { @Override ...................................................................... public double unZero() { .................................................................... } } class PolynomeAvecZeroParNewton ........................................ ...................................................................... { ... } class SerieFourierAvecZeroParNewton .................................... ...................................................................... { ... }
Analyse
L'architecture précédente possède deux couches.
Quelle est la méthode appartenant à la couche basse ?
\[ \begin{array}{llcll} \Box & \mathtt{valeur} & \quad \quad & \Box & \mathtt{unZero} \\ \end{array} \]Quelle est la méthode appartenant à la couche haute ?
\[ \begin{array}{llcll} \Box & \mathtt{valeur} & \quad \quad & \Box & \mathtt{unZero} \\ \end{array} \]Au total, avec deux sortes de fonctions, les polynômes et les séries de Fourier, et deux algorithmes de recherche d'un zéro, la dichotomie et Newton, on obtient quatre combinaisons possibles pour l'implémentation de l'interface FonctionAvecZero. Notons \(|P|\), \(|S|\), \(|D|\) et \(|N|\) les quantités de code respectivement associées aux implémentations des polynômes et des séries de Fourier et à celles des méthodes unZero par dichotomie et suivant Newton. Pour chacune des méthodes suivantes de factorisation, donner la quantité de code nécessaire pour réaliser les quatre combinaisons. Par exemple, en l'absence de factorisation, la quantité nécessaire est : \[ 2.(|P| + |S| + |D| + |N|). \] Approche ascendante par héritage
........................................................................
Approche descendante par héritage
........................................................................
Héritage multiple
........................................................................