Programmation Orientée Objet Introduction à Java

Transcription

Programmation Orientée Objet Introduction à Java
Programmation Orientée Objet
Compléments sur l’héritage
Julien Provillard
http://www.i3s.unice.fr/~provilla/poo/
[email protected]
Programmation orientée objet
Objectifs/Plan
Classes et méthodes finales
Classes internes




Classes locales
Classes anonymes
Interfaces fonctionnelles
Lambda expressions
2
CLASSES ET MÉTHODES FINALES
3
Programmation orientée objet
Classes finales
On veut pouvoir empêcher d’hériter d’une classe
 Pour préserver la sémantique contre la redéfinition par polymorphisme
 Pour des raisons de sécurités
Pour cela, on déclare une classe finale
final class A { … }
 On ne peut pas hériter d’une classe finale
 Les classes abstraites ne peuvent être finales (leur but est de servir de classe
mère)
4
Programmation orientée objet
Méthodes finales
On veut pouvoir empêcher la redéfinition de certaines méthodes d’une
classe
Pour cela, on déclare la méthode finale
class Addition {
final int calcule(int x, int y) { return x + y; }
}
 On ne peut pas redéfinir une méthode finale
 On peut hériter d’une classe qui contient des méthodes finales
5
Programmation orientée objet
Classes vs méthodes finales
Une classe finale n’est pas équivalente à une classe dont toutes les
méthodes sont finales
On peut toujours hériter d’une classe dont toutes les méthodes sont
finales pour lui ajouter de nouveaux membres.
6
Programmation orientée objet
Classes utilitaires
Une classe utilitaire est une classe
 Dont toutes les méthodes sont statiques
 Qui ne peut pas être instanciée
 Exemple: la classe java.lang.Math
Pattern de création
final class Addition { // pour empêcher l’héritage
private Addition() {} // pour cacher le constructeur par défaut
static int addition(int x, int y) { return x + y; }
}
7
CLASSES INTERNES
8
Programmation orientée objet
Classes internes
Définition
 Dans une classe
 Dans le corps d’une méthode (classes locales)
 A la volée dans une affectation ou un passage de paramètre (classes anonymes)
A la compilation
 ClasseEnglobante.class
 ClassEnglobante$1ClasseInterne.class
 ClassEnglobante$2.class
9
Programmation orientée objet
Exemple
Classe interne
class Liste {
Maillon tete;
void add(int v) { tete = this.new Maillon(v, tete); }
class Maillon {
int contenu;
Maillon suivant;
Maillon(int contenu, Maillon suivant) {
this.contenu = contenu;
this.suivant = suivant;
}
}
}
10
Programmation orientée objet
Lien avec l’objet englobant
La classe interne peut accéder aux membres (champs et méthodes) de
l’objet englobant
Accès à l’instance de la classe englobante avec <NomDeClasse>.this
Création d’une instance d’une classe interne depuis l’extérieur de la
classe englobante
 <Instance de NomDeClasse>.new <Inner>(…);
 Ex : Liste.Maillon m = l.new Maillon(10, null);
• Liste est une classe contenant une classe interne Maillon
• l est une instance de la classe Liste
11
Programmation orientée objet
Classes internes statiques
Classes internes statiques
class Liste {
Maillon tete;
void add(int v) { tete = new Liste.Maillon(v, tete); }
static class Maillon {
int contenu;
Maillon suivant;
Maillon(int contenu, Maillon suivant) {
this.contenu = contenu;
this.suivant = suivant;
}
}
}
12
Programmation orientée objet
Lien avec la classe englobante
Une classe interne ne peut avoir de membres statiques (sauf
constantes)
Une classe interne statique peut avoir des membres statiques
Création d’une instance d’une classe interne depuis l’extérieur de la
classe englobante
 new <NomDeClasse>.<StaticInner>(…);
 Ex : Liste.Maillon m = new Liste.Maillon(10, null);
• Liste est une classe contenant une classe interne statique Maillon
13
Programmation orientée objet
Cacher l’implémentation
Classe interne private
class Liste {
private Maillon tete;
void add(int v) { tete = new Liste.Maillon(v, tete); }
private static class Maillon {
int contenu;
Maillon suivant;
Maillon(int contenu, Maillon suivant) {
this.contenu = contenu;
this.suivant = suivant;
}
}
}
14
Programmation orientée objet
Classes locales
Définies dans un bloc d’instruction
N’existent pas en dehors du bloc
Utiles pour spécialiser des objets (héritage, implémentation d’interface)
sans créer une classe visible (implémentation masquée)
Ne peuvent utiliser que des variables locales final
15
Programmation orientée objet
Classes locales
Exemple
static CharSequence convert(char[] t) {
class ArrayCharSeq implements CharSequence {
char[] t;
ArrayCharSeq(char[] t) { this.t = t; }
public int length() { return t.length; }
public char charAt(int i) { return t[i]; }
public CharSequence subSequence(int i, int j) {
return new ArrayCharSeq(Arrays.copyOfRange(t, i, j));
}
public String toString() { return new String(t); }
}
return new ArrayCharSeq(Arrays.copyOf(t, t.length));
}
16
Programmation orientée objet
Opérations binaires
OperationBinaire.java
interface OperationBinaire {
double calcule(double c1, double c2);
}
Addition.java
class Addition implements OperationBinaire {
public double calcule(double c1, double c2) {
return c1 + c2;
}
}
17
Programmation orientée objet
Calculatrice
Calculatrice.java
class Calculatrice {
private double accumulateur;
private OperationBinaire addition = new Addition();
private void applique(OperationBinaire op, double v) {
accumulateur = op.calcule(accumulateur, v);
}
void add(double x) {
applique(addition, x);
}
}
Doit-on réellement définir la classe Addition?
Instanciation unique
18
Programmation orientée objet
Classes anonymes
Calculatrice.java
class Calculatrice {
private double accumulateur;
private OperationBinaire addition =
new OperationBinaire() {
public double calcule(double c1, double c2) {
return c1 + c2;
}
};
private void applique(OperationBinaire op, double v) {
accumulateur = op.calcule(accumulateur, v);
}
void add(double x) {
applique(addition, x);
}
}
19
Programmation orientée objet
Classes anonymes
 Une classe sans nom définie par
 new <NomClasse>(…) { … }
 ou new <NomInterface>() { … }
 Spécialise n’importe quelle classe, interface ou classe abstraite
 Une classe anonyme ne peut pas avoir de constructeur !
 Ne peuvent utiliser que des variables locales final
Point getP(double x, double y) {
return new Point(x, y) {
public String toString {
return "Point anonyme (" + x + "," + y + ")";
}
};
}
20
Programmation orientée objet
Interface fonctionnelle (JDK 8.0)
Une interface est dite fonctionnelle si elle ne contient qu’une seule
méthode abstraite
 OperationBinaire est une interface fonctionnelle
interface OperationBinaire {
double calcule(double c1, double c2);
}
21
Programmation orientée objet
Interface fonctionnelle (JDK 8.0)
Une interface fonctionnelle peut contenir plusieurs méthodes si elles
ont des implémentations par défaut
 OperationBinaire est une interface fonctionnelle
interface OperationBinaire {
double calcule(double c1, double c2);
default double iter(double acc, double... args) {
for (double arg : args)
acc = calcule(acc, arg);
return acc;
}
}
22
Programmation orientée objet
Lambda expressions (JDK 8.0)
Une interface fonctionnelle peut être implémenter de manière
anonyme par une lambda expression
Syntaxe
 arg -> expression
 (arg1, arg2, ..., argn) -> expression
 (arg1, arg2, ..., argn) -> { ... // instructions
return ...; }
Type des arguments optionnel (inférence de type)
 (x, y) -> x + y

(int x, int y) -> { return x + y; }
 Suivent exactement les mêmes règles que les classes anonymes
23
Programmation orientée objet
Lambda expressions (JDK 8.0)
Calculatrice.java
class Calculatrice {
private double accumulateur;
private OperationBinaire addition = (c1, c2) -> c1 + c2;
private void applique(OperationBinaire op, double v) {
accumulateur = op.calcule(accumulateur, v);
}
void add(double x) {
applique(addition, x);
}
}
24
Programmation orientée objet
Références sur méthodes (JDK 8.0)
On peut définir une opération binaire de la manière suivante :
OperationBinaire op = (c1, c2) -> Math.max(c1, c2);
En fait, on applique la méthode statique max de la classe Math. Peut-on
l’exprimer de manière plus directe?
Oui!
OperationBinaire op = Math::max;
 Math::max est une référence sur la méthode max de la classe Math et est
équivalente à une lambda-expression.
25
Programmation orientée objet
Références sur méthodes (JDK 8.0)
On peut référencer différents type de méthode et même des
constructeurs.
Type de méthode
Syntaxe
Exemple
Equivalence
Méthodes statiques
<class>::<staticMethod>
Méthode d’instance
d’un objet
<object>::<instanceMethod> "toto"::compareTo
x -> "toto".compareTo(x)
Méthode d’instance
d’une classe
<class>::<instanceMethod>
String::compareTo
(x, y) -> x.compareTo(y)
Constructeur
<class>::new
StringBuilder::new () -> new StringBuilder()
Math::max
(x, y) -> Math.max(x, y)
26