Vous êtes sur la page 1sur 43

PROGRAMMATION

JAVA
Deuxième année Informatique (ENICARTHAGE)

1
CONCEPTS ORIENTÉ
OBJET EN JAVA
2
CLASSES ET OBJETS
❖ Une classe est une abstraction ou « type complexe » regroupant un ensemble de données (que
l’on nomme attributs), et un ensemble de méthodes de traitements (que l’on nomme
méthodes)
❖ Les objets sont des représentations dynamiques (instanciation), des classes. L'opérateur
instanceof permet de tester à l'appartenance d'un objet à une classe donnée.
❖ Un constructeur est une méthode invoquée lors de la création d’un objet (initialisation). Il est
à définir dans chaque classe
// exemple avec code en Java :
// Une ville est caractérisée par son nom en majuscules et son nombre d’habitants positif
public class Ville {
String nom;
int nbHabitants;
//constructeur complet
public Ville(String nom, int nbHabitants) {
this.nom= nom.toUpperCase();
if (nbHabitants<=0) System.out.println ("nbHabitants doit être positif !");
3
else this.nbHabitants=nbHabitants; } }
RQ 1: si le constructeur était Ville(String nomVille, int nombre) c’est-à-dire avec des
arguments dont les appellations sont différentes de celles des attributs on peut omettre le mot clé
« this ».
RQ 2: On peut avoir plusieurs constructeurs:

public Ville(String nomVille) {


nom=nomVille.toUpperCase();}

public Ville(String nomVille, int nombre) {


// le mot clé this fait appel à un autre constructeur avec les mêmes arguments
this(nomVille);
if (nombre<=0) System.out.println ("nbHabitants doit être positif !");
else nbHabitants=nombre; }

// dans une classe principale


public class Test {
public static void main(String[] args) {
// instantiations
Ville v =new Ville("Tunis");
Ville e = new Ville("Sousse", 600000); }

4
RQ 3: On peut ajouter des méthodes dans la classe Ville
public boolean nbHabConnu() {
return nbHabitants >0; }
public void afficher() {
if (nbHabConnu()) Ville ( TUNIS, nombre d’habitants inconnu )
System.out.println("Ville ( "+nom+", "+nbHabitants+" ) "); Ville ( SOUSSE, 600000 )
else
System.out.println("Ville ( "+nom+", nombre d'habitants inconnu ) "); }

// appel dans la classe principale


v.afficher();
e.afficher();

// exemple 1 de classe existante: classe Scanner


import java.util.Scanner; // le package dans lequel se trouve la classe Scanner
public class TestScanner {
public static void main(String[] args) { Veuillez saisir un entier: 2022
Scanner scanner = new Scanner( System.in ); Veuillez saisir une chaine de caractères: enicar
System.out.println( "Veuillez saisir un entier : " ); enicar 2022
int a = scanner.nextInt();
System.out.println( "Veuillez saisir une chaine de caractères : " ); Autres méthodes:
String str= scanner.next(); nextLine(), nextDouble(), 5
System.out.println(str+ " " +a); }
// exemple 2 de classe existante: classe StringBuffer
public class TestStringBuffer {

public static void main(String[] args) { longeur:9


StringBuffer sf1 = new StringBuffer("Bienvenue"); capacité:25
System.out.println("longeur:"+sf1.length()); longeur:26
System.out.println("capacité:"+sf1.capacity()); capacité:42
StringBuffer sf2 = new StringBuffer("Bienvenue aux groupes info");
System.out.println("longeur:"+sf2.length());
System.out.println("capacité:"+sf2.capacity());
}

❖ Quelques méthodes supplémentaires:


✔ StringBuffer append(p) : ajoute p en fin de chaîne (p est n'importe quel type de base)
✔ StringBuffer insert(int offset, p) : idem, mais en insérant p à l'emplacement indiqué par offset
✔ StringBuffer reverse() : inversion des caractères de la chaîne

6
HÉRITAGE
Exemple: une voiture est un véhicule (héritage), une voiture possède un moteur
(composition), une voiture appartient à un propriétaire (agrégation).
❖ L’idée principale de l’héritage est d’organiser les classes de manière hiérarchique. Ce
mécanisme permet d'ajouter des fonctionnalités à une classe (une spécialisation) en créant une
sous-classe (ou classe dérivée) qui hérite des propriétés de la classe parente (ou super-classe)
et à laquelle on peut ajouter des propriétés nouvelles; on utilise la clause extends
❖ En java, on ne parle que d'héritage simple

7
ENCAPSULATION
❖ L'encapsulation consiste à masquer les données au sein des classes et à manipuler leur
contenu qu'au moyen de méthodes publiques mécanisme du contrôle d’accès aux
membres
public private
Attributs Attribut accessible directement Attribut accessible uniquement dans
depuis code de n’importe quelle classe le code de la classe qui le définit
Méthodes Méthode pouvant être invoquée Méthode utilisable uniquement dans
depuis le code de n’importe quelle le code de la classe qui la définit
classe

On doit respecter le maximum de ces règles:


✔ Les attributs doivent être privés
✔ Les méthodes à usage strictement internes doivent être privées 8

✔ Si un attribut doit pouvoir être accessible de l’extérieur, définir des méthodes publiques permettent d’y accéder
(getters/setters).
OBJECT: MÈRE DE TOUTES LES
CLASSES
❖ La super-classe par défaut est « Object »: Cette classe est la racine unique de l'arbre
des classes et elle est la seule classe Java qui ne possède pas de classe parente.
❖ Toutes les classes héritent des méthodes de la classe Object (par exemple toString( ),
equals( ),...
❖ Quelques méthodes qu’on peut soit utiliser telles qu’elles soit redéfinies :
✔String toString() : retourne un String contenant le nom de la classe concernée et
l’adresse de l’objet en hexadécimal (précédée @)
✔boolean equals() : retourne un booléen qui compare les adresses de deux objets

9
LES ANNOTATIONS
❖ En Java, une annotation constitue une métadonnée que l'on peut appliquer à différents
éléments du code source. Les annotations n'ont pas d'effet direct sur le fonctionnement
des instructions annotées. Le caractère '@' indique au compilateur que l'identificateur
qui suit est une annotation.
Exemple d’annotation standard :
@Override indique au compilateur que la méthode redéfinit une méthode héritée. Il
pourra ainsi générer une erreur si l’entête n’est pas correcte. Sans l’annotation
@Override le code fonctionne parfaitement (et de manière identique) mais le
programmeur ne serait pas averti qu’il crée une nouvelle méthode d’instance (faute de
frappe par ex.) alors qu’il voulait redéfinir une méthode d’une des classes parentes.

10
// exemple des formes géométriques
public class Point { public class Rectangle extends Point {
private double x,y; private double longueur,largeur;
public Point(double x, double y){ public Rectangle(double x, double y, double longueur, double
this.x=x; this.y=y; } largeur){
super(x,y);
public void deplacer (double dx, double dy){ this.longueur=longueur;
x+=dx; y+=dy; } this.largeur = largeur;}
public double surface(){
public double getX(){return x;} return longueur*largeur; }
public double getY(){return y;} public double perimetre(){
public void setX(double x){this.x=x;} return 2*(longueur+largeur); }
public void setY(double y){this.y=y;}
public double getLongueur(){return longueur;}
// méthode toString public void setLongueur(double longueur){this.longueur=longueur;}
@Override public double getLargeur(){return largeur;}
public String toString(){ public void setLargeur(double largeur){this.largeur=largeur;}
return "Point:"+" ("+x+","+y+" )"; } // méthode toString
@Override @Override
public boolean equals(Object o){ public String toString(){
Point p = (Point) o; return "Rectangle:"+" ("+getX()+","+getY()+" )de longueur "
return ((x==p.x) && (y==p.y)) ;} +getLongueur()+" de largeur "+getLargeur();
} }
11
}
public class Cercle extends Point {
private double r;
public Cercle(double x, double y, double r){
super(x,y);
this.r=r; }
public double surface(){
return Math.PI*r*r; }
public double perimetre(){
return 2*Math.PI*r; }
public double getR(){return r;}
public void setR(double r){this.r=r;}
// méthode toString
@Override
public String toString(){
return "Cercle:"+" ("+getX()+","+getY()+" )+ de rayon "+getR();}
// méthode equals
@Override
public boolean equals(Object o){
Cercle c = (Cercle) o;
return
((this.getX()==c.getX())&&(this.getY()==c.getY())&&(this.getR()==c.getR()));
}
}
12
public class FormesGeom {
private static final int Nmax =5; // constante
public static void main(String[] args) {
// création d'un tableau statique de taille 5 contenant des formes géométriques
Point[] tabformes = new Point[Nmax];
tabformes[0] = new Point(1,2);
tabformes[1] = new Point(5,-2);
tabformes[2] = new Point(-1,2);
tabformes[Nmax-2]=new Cercle(0,0,5); // possible par polymorphisme
tabformes[Nmax-1]=new Rectangle(0,0,5,4); // possible par polymorphisme
// déplacement de tous les éléments
for (int i=0;i<Nmax;i++)
{tabformes[i].deplacer(-4, 6);}
// test de toString
for (int i=0;i<Nmax;i++) {
System.out.println(tabformes[i]);} Point: (-3.0,8.0 )
Point: (1.0,4.0 )
Point pt = new Point(1,2); Point: (-5.0,8.0 )
Point pt1 = new Point(1,-2); Cercle: (-4.0,6.0 )+ de rayon 5.0
System.out.println(pt.equals(pt1)); Rectangle: (-4.0,6.0 )de longueur 5.0 de largeur 4.0
Cercle cr = new Cercle(1,2,5); false
Cercle cr1 = new Cercle(1,2,5); true
System.out.println(cr.equals(cr1));
} } 13
CLASSES SCELLÉES
❖ Classiquement parlant, pour qu’une classe ne peut pas être héritée on précède sa
déclaration du mot clé final
❖ Depuis le Java SE 17, il est maintenant possible de restreindre les possibilités
d'héritage, sans complètement les interdire : pour ce faire, on peut définir des classes
scellées.
❖ Pour définir une classe scellée, on utilise le mot clé contextuel sealed. On complète la
définition via le mot clé contextuel permits pour indiquer quels sont les types
autorisés à dériver de la classe scellée.
// exemple: supposons l’existence d’une classe Point
public sealed class Shape permits Circle, Square {
private Point center;
// autres attributs et méthodes.
}
14
// la déclaration de cette classe est permise // erreur de compilation dans ce cas
public final class Circle extends Shape { public final class Triangle extends Shape {
private double radius; //attributs et méthodes.
//autres attributs et méthodes. }
}

Classe dérivée d’une classe scellée :


❖ Lors d’un héritage, on doit passer obligatoirement par l’une des trois stratégies :
Sous classe final qui permet d’interdire une éventuelle sous-classe
Sous classe scellée aussi précédée alors par le mot clé sealed
Sous classe ouverte alors elle sera précédée par le mot clé non-sealed. On indique au compilateur qu’on
peut dériver de cette sous-classe tout type de données.

public final class Circle extends Shape { public sealed class Circle extends Shape public non-sealed class Circle extends
private double radius; permits cylinder { Shape {
//autres attributs et méthodes. private double radius; private double radius;
} //autres attributs et méthodes. //autres attributs et méthodes.
} }
public final class Cylinder extends Circle { public class Cylinder extends Circle {
private double height; private double height;
//autres attributs et méthodes. //autres attributs et méthodes.
} } 15
In Java, a static method is a method that belongs to the class itself rather than to instances (objects) of the class. It
is associated with the class as a whole rather than with any specific object of that class.

MOT CLÉ STATIC


❖ Les membres statiques sont des membres dont la déclaration est précédée du modificateur
static. Ils sont définis et invoqués indépendamment des instances.
❖ Exemples:
invocation des membres statiques de la classe Math
Math.PI Math.cos(x) Math.toRadians(90)
Méthode statique random de Math vue précédemment
Méthodes statiques des classes enveloppantes
Méthode statique hashcode de la classe Objects qui permet de donner un message «crypté » à
partir d’un String et d’un nombre (exemple double)
Méthodes statiques de la classe Arrays

16
// exemple méthode statique compare de Double
Double.compare( double, double)
/* La méthode statique Double.compare renvoie une valeur négative si le premier argument est
inférieur au deuxième argument, 0 si elles sont égales et une valeur positive sinon.*/
// exemple des méthodes statiques des classes Math et Arrays
import java.util.Arrays;
public class Test {
public static void main(String[] args) {
double[] vec = new double[5];
for (int i = 0; i < vec.length; i++) vec[i] = Math.random()*1000;
// idem avec la boucle forEach
//for (double i : vec) i = random()*1000;
Arrays.sort(vec); // tri du tableau
for (int i = 0; i < vec.length; i++) System.out.print(vec[i] + " " ); // affiche le tableau trie
System.out.println(" ");
int pos = Arrays.binarySearch(vec,500); // recherche de la valeur 500 dans vec qui doit être trie
if (pos >= 0)
System.out.println("position de 500 : " + pos);
else System.out.println("500 n ’est pas dans le tableau");
}
}
4.6652900881679615 105.81253320075557 245.8614229708177 347.04714262089766 705.723839992852
500 n ’est pas dans le tableau 17
DES CLASSES IMMUABLES
AUX RECORDS
❖ Une classe immuable (readOnly) permet de produire des objets avec un état initial mais qui
ne pourront plus changer d'état une fois instanciés.
❖ Pour avoir une classe immuable il suffit que :
les attributs soient précédés par le mot clé private final (attention c’est différent de static
final pour les constantes)
ne pas créer des setters
❖ Les records sont des nouveaux types de classes immuables en Java. Ce concept est apparu à
partir de la version Java SE 16.
// exemple
public record Animal (String nom, double age) {}
/* automatiquement par cette déclaration on génère une classe finale qui étend la classe Record avec les éléments suivants :
un champ privé et final par élément défini dans l’entête du record. Chaque champ reprend le nom défini dans le record
c’est-à-dire private final String nom et private final double age, 18
un accesseur (getter) public par élément du record, avec comme nom, le nom de l’élément c’est dire dans notre
cas deux getters: String nom() et double age()
les méthodes toString, equals et hashCode */

public class Principale {


public static void main( String[] args ) { Animal[nom=chat, age=2.0]
Animal a1 = new Animal("chat" , 2.0 ); Animal[nom=chien, age=5.0]
System.out.println( a1 ); Egalité : false
Animal a2 = new Animal("chien" , 5.0 ); Hash code : -286354093
System.out.println( a2 ); Getters : chien - 5.0
System.out.println( "Egalité : " + ( a1 == a2 ) );
System.out.println( "Hash code : " + a2.hashCode() );
System.out.println( "Getters : " + a2.nom() + " - " + a2.age() );
}}

❖ Il est possible d’ajouter des méthodes (d’instances et statiques), d’ajouter des champs statiques
(mais pas de champs d’instance en dehors de l’entête du record), de créer des constructeurs, et
de redéfinir toutes les méthodes générées.
❖ Seulement, l’ajout d’un nouveau constructeur écrase celui proposé par le record
19
CLASSES IMBRIQUÉES
❖ Les classes imbriquées ou internes sont définies au même niveau qu’une méthode ou un
attribut dans une autre classe (composition).
// exemple
public class Voiture { public class Imbrication {
private int puissance; public static void main(String[] args) {
// classe imbriquée Voiture vo = new Voiture("Amine",5) ;
public class Roue { }
private String modele; }
Roue (String mod) {this.modele = mod;}}
// autre attribut
private Roue[] roues = new Roue[4];
// constructeur de la classe Voiture
public Voiture (String modele_roue, int puiss)
{ this.puissance = puiss;
for (int i=0; i<roues.length;i++) roues[i] = new Roue
(modele_roue);
}} 20
LES CLASSES ABSTRAITES
❖ Une classe concrète est une classe à partir de laquelle on peut instancier des objets. Si on ne
veut pas créer des instances spécifiques de la classe on parle de classe abstraite
❖ Le seul but de la création de classes abstraites est de permettre à d’autres classes de les hériter
exemple:

21
abstract class Forme { class Cercle extends Forme { class Rectangle extends Forme {
String couleur; double rayon; double hauteur;
public Cercle(String couleur, double rayon) { double largeur;
// méthode abstraite super(couleur); public Rectangle(String couleur,
abstract double surface(); this.rayon = rayon; double hauteur, double largeur) {
} super(couleur);
// constructeur this.hauteur = hauteur;
public Forme(String couleur) @Override this.largeur = largeur;
{ double surface() { }
this.couleur = couleur; return Math.PI * Math.pow(rayon, 2);
} }} @Override
double surface() {
// méthode concrète return hauteur * largeur;
public String getCouleur() { }}
return couleur;
} }

public class Test {


public static void main(String args[]) {
Forme f1 = new Cercle("Rouge", 2.2);
Surface : 15.205308443374602
System.out.println("Surface : " + f1.surface());
Surface : 8.0
Forme f2 = new Rectangle("Vert", 2, 4);
System.out.println("Surface : " + f2.surface()); }
} 22
LES INTERFACES
// exemple introductif
// supposons que les deux classes Rectangle et Cercle héritent de la classe concrète PointColore
public class PointColore {
protected double x,y; //
protected String couleur;
public PointColore(double x, double y, String couleur){
this.x=x; this.y=y; this.couleur=couleur;}
// autres méthodes
}
public class Cercle extends PointColore {
protected double rayon;
public Cercle(double x, double y, String couleur, double rayon) {
super(x,y,couleur);
this.rayon = rayon; }
//autres méthodes
}
23
public class Rectangle extends PointColore{
protected double hauteur;
protected double largeur;
public Rectangle(double x, double y, String couleur, double hauteur, double largeur) {
super(x,y,couleur);
this.hauteur = hauteur;
this.largeur = largeur; }
// autres méthodes
}
// supposons l’existence de la classe abstraite Forme qui renferme deux méthodes abstraites surface() et perimetre()
/* si on veut implémenter ces deux méthodes dans les classes Cercle et Rectangle telle que on l’a fait précédemment
on doit les hériter de la classe Forme ce qui n’est pas possible vu que l’héritage multiple n’est pas pemis*/
// solution: de la classe abstraite on définit l’interface Forme avec deux méthodes abstraites
public Interface Forme {
double surface();
double perimetre(); }
// au niveau entêtes des classes Rectangle et Cercle
public class Cercle extends PointColore implements Forme {….}
public class Rectangle extends PointColore implements Forme {….}
// on implémente maintenant les méthodes abstraites dans ces classes

24
❖ L’interface n'est pas une classe; c'est presque la même chose qu'une classe abstraite,
sauf qu'une interface contient, très souvent, que des méthodes abstraites
❖ L’interface n’est pas aussi instanciable.
❖ Les interfaces sont très utiles du point de vue de la conception des librairies et on trouve
un grand nombre dans le Java SE ou dans le Jakarta EE. Elles sont au cœur de
l’implémentation de beaucoup de bibliothèques et de frameworks.
❖ Une interface permet de définir un ensemble de services qu’un client peut obtenir d’un
objet ce qui permet le découplage entre un service et son implémentation. En règle
générale, le fournisseur de certains services déclare: «Si votre classe se conforme à une
interface particulière, le service sera exécuté.»
Exemple: service de comparaison
public interface Comparable
{
int compareTo(Object o);
// pas besoin de public car les méthodes des interfaces sont automatiquement publiques
}
/* Si on voulait effectuer les comparaisons des objets d’une classe selon l’un de ses paramètres, cette classe
peut implémenter l’interface Comparable et définir la méthode compareTo*/
public class Professeur implements Comparable
25
private String nom;
private double salaire;
public Professeur(String nom, double salaire){
this.nom=nom;
this.salaire=salaire;
}
@Override
public int compareTo(Object autreProf)
{
Professeur p= (Professeur) autreProf;
return Double.compare(salaire,p.salaire);
/* Rappelons que la méthode statique Double.compare renvoie une valeur négative si le premier argument est inférieur au
deuxième argument, 0 si elles sont égales et une valeur positive sinon.*/
}}

// remarques:
Comparable x= new Comparable() ;// Erreur
Comparable x; // on peut déclarer une variable d’interface instanciable par une classe qui l’implémente
// si Professeur implémente Comparable
Comparable x = new Professeur("Mostafa",7000); // ou tout court x = new Professeur("Mostafa",7000);
// on peut utiliser instanceof pour vérifier si un objet implémente une interface:
if (p instanceof Comparable){
} 26
❖ Une classe peut implémenter une ou plusieurs interfaces en utilisant la syntaxe
suivante (s’engage aussi de fournir la description complète de ses méthodes
abstraites) : implements interface1, interface2,...
❖ Les interfaces peuvent avoir des sous-interfaces. On utilise le mot clé: extends.
Contrairement aux classes, une interface peut posséder plusieurs interfaces parentes.
exemple : public interface Zoomable extends Modifiable, Translatable, Rotatable {...}
❖ Une classe qui implémente une sous-interface doit implémenter les méthodes
abstraites définies directement par l'interface ainsi que les méthodes abstraites héritées
de toutes les interfaces parentes de la sous-interface
❖ Depuis Java 8, On peut ajouter des méthodes statiques aux interfaces. Il n'y a jamais
eu de raison technique pour interdire cette pratique, même qu’il semblait contraire à
l'esprit des interfaces en tant que SPÉCIFICATIONS abstraites.
// exemple: else { if (x==y) return 0;
public Interface Forme { else return -1; } } }
double surface(); // on peut appeler cette méthode par:
double perimetre(); int i = Forme.comparer(2.0,5.0);
static int comparer (double x, double y) {
if (x>y) return 1;
27
❖ On peut mettre des attributs dans une interface mais ils doivent être des constantes sans
mettre static final.
❖ Scénario: Supposons que nous devions ajouter une nouvelle méthode dans une
interface (ajout d’une exigence pour un service). Nous pouvons ajouter facilement la
méthode dans notre interface sans implémentation (méthode abstraite). Cependant,
toutes les classes qui implémentent cette interface doivent fournir une implémentation
pour la méthode A réfléchir si le nombre de ces classes est grand!!
❖ Solution: Depuis Java 8, des méthodes avec implémentation (méthodes par défaut) ont
été introduites dans une interface, elle seront héritées comme méthodes ordinaires qu’on
peut les laisser ou redéfinir.
// exemple:
public Interface Forme { La méthode afficher () est appelée par les
double surface(); objets des classes implémentant l’interface
double perimetre(); Forme
default void afficher() {
System.out.println ("Formes géométriques" );
}}

28
// Problème: Conflit des méthodes par défaut des interfaces
interface Personne
{ default String getName() { return ""; };}
interface Employe
{ default String getName() { return getClass().getName(); } }

class Professeur1 implements Personne, Employe{….}


// La classe hérite deux méthodes getName() incohérentes fournies par les interfaces Personne et Employe
// Java signale une erreur et laisse au programmeur le soin de résoudre l’ambiguïté.
// exemple de résolution:
class Professeur1 implements Personne, Employe{
public String getName() {
return Personne.super.getName();} }
// si le conflit était entre une méthode par défaut d’une interface et une méthode d’une superclasse
// par exemple dans notre cas si Personne était une classe et Employe était une interface
class Professeur extends Personne implements Employe { ... }
/* Dans ce cas, seule la méthode superclasse compte et toute méthode par défaut de l'interface est simplement ignorée:
«classe gagne». Pour cela, dans les interfaces ne pas mettre des méthodes par défaut avec les appellations toString et
equals…*/

29
❖ De plus, les interfaces prennent en charge les méthodes privées avec la version Java 9.
On peut désormais utiliser des méthodes privées dans les interfaces. Puisque on ne peut
pas instancier les interfaces, les méthodes privées sont utilisées comme méthodes d'aide
qui fournissent le support à d'autres méthodes dans les interfaces (appelées par d’autres
méthodes statiques ou par défaut dans l’interface).

30
LES INTERFACES

FONCTIONNELLES
Une interface fonctionnelle est une interface comprenant exactement une seule
méthode abstraite. Cependant, elle peut contenir des constantes, des méthodes avec une
implémentation par défaut, des méthodes statiques et des méthodes privées.
exemple: public interface Printable { void print();}
❖ Même que ces interfaces existaient dans des versions précédentes cette appellation n’a
apparue qu’avec la version Java 8.
❖ A partir de Java 8, L’annotation @FunctionalInterface est utilisée pour s’assurer que
l’interface fonctionnelle ne peut pas avoir plus d’une méthode abstraite. Si plusieurs
méthodes abstraites sont présentes, le compilateur signale un message "Unexpected
@FunctionalInterface annotation". Cependant, il n'est pas obligatoire d'utiliser cette
annotation.
❖ Des exemples d’interfaces fonctionnelles existantes: Runnable, Comparable…
31
LES EXPRESSIONS LAMBDA
❖ A partir de Java 8, l'expression lambda introduit un nouvel élément de syntaxe et un nouvel
opérateur en langage Java. Le nouvel opérateur est appelé opérateur lambda ou opérateur flèche
(->).
❖ Syntaxe: (liste d'arguments) -> { corps lambda }
❖ l'expression lambda n'est pas exécutée seule. Au contraire, elle constitue la mise en œuvre de
la méthode abstraite définie par l'interface fonctionnelle.
@FunctionalInterface
interface Forme {
int calculer(int x); }

public class Test {


public static void main(String args[]) {
// nous affectons l'expression lambda à l'instance de la classe anonyme implémentant l'interface fonctionnelle
Forme s = (int x) -> x * x; int ans = s.calculer(5); System.out.println(ans); } }
25 32
// deuxième exemple
import java.util.Arrays;
@FunctionalInterface
interface TabOperation {
// méthode abstraite pour inverser les éléments d'un tableau
int[] inverser(int[] x); }

public class Test {


public static void main(String args[]) {
int[] T = { 3, 5, 7, 8 };
/* nous affectons l'expression lambda à l'instance d’une classe anonyme implémentant l'interface fonctionnelle
TabOperation*/

TabOperation tab = (int[] Tab) -> {


int Taille = Tab.length;
int[] inv = new int[Taille];
for (int i = 0; i < Taille; i++) {
inv[i] = Tab[(Taille - i) - 1];
}
return inv; };
int[] T2 = tab.inverser(T);
System.out.println(Arrays.toString(T2)); /* méthode statique de la classe Arrays rendant le tableau comme chaine
de caratères*/
[8, 7, 5, 3]
}} 33
RÉFÉRENCES AUX MÉTHODES
❖ Comme les expressions Lambda permettent d’exprimer une méthode fonctionnelle d’une
interface fonctionnelle en introduisant le code correspondant à l’emplacement où l’on a
besoin, les références de méthodes vont offrir une autre sorte de raccourci qui peut s’appliquer
à des méthodes statiques, des méthodes de classe, des méthodes associées à un objet
particulier ou à des constructeurs
// exemple public interface Distanciable {
public class Point { public double distance(Point p1, Point p2); }
double x, y; public class TestReferences {
public Point (double x, double y) public static void main(String[] args) { 81
{this.x=x ; this.y=y;} // référence à une méthode statique 3.1622776601683795
public static double calcul( Point p1, Point p2){ Calculable cal = Point::carre;
return(Math.sqrt((p1.x-p2.x)*(p1.x-p2.x) System.out.println(cal.calculer(9));
+(p1.y-p2.y)*(p1.y-p2.y)));} // référence à une méthode de classe
// méthode statique Point p1 = new Point(5,4);
public static int carre(int n){return n*n;}} Point p2 = new Point(2,5);
public interface Calculable { Distanciable db = Point::calcul;
public int calculer(int n) ; } System.out.println(db.distance(p1,p2)); } } 34
❖ Référence à un constructeur
// constructeur de la classe A : A ::new

35
PACKAGE
❖ Un paquetage (ou package) est un regroupement logique de classes, interfaces,
énumérations, annotations ou sous packages sous forme de bibliothèque de programmes
❖ Le package java.lang comporte les classes de base pour Java. Il est importé automatiquement
par le compilateur. Si nous avons besoin d’une classe hors de ce package nous devons
l’importer par le mot clé « import »
❖ sous Apache NetBeans IDE 19

(…)

NB: Ce sont les modules


et pas les packages

36
Les packages de Java.base

(…)

37
Le contenu de de Java.lang

(…) (…)

38
Le contenu de de Java.util

// Exemple: classe Date dans java.util


// juste la classe est importée
import java.util.Date ;
Ou
// toutes les classes sont importées
(…) (…) import java.util.* ;
// création d’un objet now
java.util.Date now = new java.util.Date
();

39
❑ L'importation d'un package entier (....*) ne rend pas visible le contenu des éventuels sous-paquetages.
❑ En cas de conflit (importation de packages contenant des classes portant le même nom), le compilateur
imposera l'utilisation du nom complet pour accéder aux classes homonymes.

40
❑ Solution pour réduire le code concernant les membres statiques: l'import statique (static import).
// Exemple:
import static java.lang.Math.*;
public class Test{
public static void main(String[] args) {
System.out.println(PI); System.out.println(cos(0)); } }

❑ Les packages servent également à gérer les droits d'accès (visibilité) des classes les unes par rapport
aux autres.
public protected private Par défaut

Dans la même classe oui oui oui oui


Dans une classe d’un même package oui oui non oui
Dans une sous-classe d’un autre package oui oui non non

Dans une classe quelconque d’un autre oui non non non
package

41
❖Dans un même projet on peut créer un ou plusieurs packages. Lors de la création d’une
classe on doit l’affecter à un package. Le mot clé est « package ». En l’absence d’instruction
package (déconseillé), le compilateur considère que les classes du programme appartiennent
à un package « par défaut » (anonyme)
❖ sous Apache NetBeans IDE 19

Dans un fichier de
classe:
42
LES MODULES
❖ Notion supportée à partir de Java 9, et en production avec la version LTS Java 11
❖ Un module est un ensemble de classes et de packages qui peut se présenter sous la
forme d’un répertoire ou d’un fichier JAR.
❖ Les modules ont été introduits pour améliorer la sécurité et pour permettre une meilleure
modularité de la plate-forme Java.

43

Vous aimerez peut-être aussi