abstract void methodeAbstraite();
abstract class ClasseAbstraite { ... }
ClasseAbstraite unObjet; //compile
unObjet = new ClasseAbstraite(); //ne compile pas
L'abstraction sert à regrouper sous une même étiquette une catégorie d'objets, éventuellement de classes différentes, qui ont un point commun. Si seul ce point commun compte dans un programme, il est raisonnable que tous les objets de cette catégorie puissent être utilisés quelle que soit leur classe.
Par exemple, on peut raisonnablement dessiner une moto, une voiture, un train, un avion quand on nous le demande. En revanche, si on nous demande de dessiner un véhicule, qui est une catégorie plus abstraite, on voudra plus de précisions. Cependant, on sait que l'action de se déplacer est commune à tous les véhicules.
Integration.java
qui permet d'intégrer numériquement la fonction \(g : \mathbb{R} \rightarrow \mathbb{R}\)
telle que \(g(x) = x^2\). System.out.println("sur ["+a+","+b+"] par pas de "+delta);
double sum = 0;
for (double x = a; x <= b; x += delta)
sum += x*x * delta;
return sum;
evaluer
d'une classe FonctionCarre
que vous instanciez au début du calcul. sum += g.evaluer(x) * delta;
Trinome
qui modélise la fonction t
.
Ajoutez un paramètre formel de type Trinome
à la méthode de calcul
et modifiez l'appel de la méthode en conséquence.FonctionDeRDansR
possédant une méthode abstraite evaluer
qui donne \(f(x)\) à partir de \(x\).Trinome
à FonctionDeRDansR
dans la méthode calculer
.Sinusoide
qui modélise la fonction
\(s : \mathbb{R} \rightarrow \mathbb{R}\) telle que
\(s(x) = Acos(x) + Bsin(x)\).
Testez avec une instance de la classe Sinusoide
.Une interface est un ensemble de requêtes. Toutes les instances des classes implémentant une même interface répondent (à leur manière) à toutes ces requêtes et sont donc de ce point de vue interchangeables.
Il existe des appareils très différents fournissant un signal audio/vidéo (lecteur Blu-ray, ordinateur, console de jeu). Vous pouvez pourtant tous les relier à votre téléviseur par un connecteur approprié (HDMI) pourvu qu'ils respectent tous la même interface (norme et prise).
Une interface I
liste toutes les requêtes qu'on peut adresser aux
instances des classes l'implémentant:
interface I {
void unePremiereRequete();
...
}
Une classe implémentant I
est déclarée ainsi:
class A implements I { ... }
NB. Une classe peut dériver d'une autre et implémenter plusieurs interfaces:
class B extends A implements J, K { ... }
Interfaces et classes (abstraites) partagent le mécanisme de polymorphisme; des objets de classes différentes sont interchangeables à partir du moment où leurs classes héritent d'une même classe parente ou implémentent la même interface.
abstract class A { ... }
class B extends A { ... }
interface I { ... }
class C implements I { ... }
A objetA = new B(); //transtypage ascendant implicite
I objetI = new C(); //idem
void push(int aValue)
(empiler)void pop()
(dépiler)int top()
(haut de la pile)boolean empty()
(est vide ?)Stack
qui liste ces requêtes.DynamicArray
qui modélise un
tableau dynamique (dont la capacité de stockage s'accroit en fonction du nombre d'éléments
ajoutés au tableau).StackByArray
, qui dérive de DynamicArray
et qui implémente l'interface Stack
.TestStack.java
.Finalement, pour savoir si l'héritage entre deux classes est approprié, l'important est de se demander si on veut exploiter
Si on veut exploiter ces deux propriétés en même temps, l'héritage convient (mais c'est plutôt rare).
Dans le cas 1., une relation de composition pourrait être préférée.
Dans le cas 2., mieux vaut considérer l'utilisation d'une classe abstraite ou d'une interface.