Programmation Orientée Objet
Concept de classe
• En Java, tout appartient à une classe sauf les variables de types primitifs.
• Une classe est un ensemble de données et de fonctions regroupées dans une même
entité. Elle est considérée comme une description abstraite d'un objet.
• Une classe représente un type de données d’objets que les développeurs vont créer.
• Les fonctions qui opèrent sur les données sont appelées des méthodes et ces données
sont appelées des attributs.
• Instancier une classe consiste à créer un objet sur son modèle (une classe).
• Une classe comporte, dans sa déclaration, des variables (la déclaration des données et des
constantes) et les définitions des méthodes.
• Les méthodes et les données sont pourvues d'attributs de visibilité qui gèrent leur
accessibilité par les composants hors de la classe.
Concept de classe
• La syntaxe de déclaration d'une classe est la suivante :
modificateurs class nom_de_classe [extends classe_mere] [implements interfaces] { ... }
• Le mot-clé extends permet de spécifier une superclasse éventuelle : ce mot clé permet de
préciser la classe mère dans une relation d'héritage.
• Le mot-clé implements permet de spécifier une ou des interfaces que la classe
implémente. Cela permet de récupérer quelques avantages de l'héritage multiple.
Créer une classe
• On va créer une classe Rational constituée de deux entiers: numerator et denominator.
Objets
• Les objets contiennent des attributs et des méthodes.
• Les attributs sont des variables ou des objets nécessaires au fonctionnement de l'objet.
• La classe est la description d'un objet et un objet est une instance d'une classe.
• Pour chaque instance d'une classe, le code est le même, seules les données sont
différentes à chaque objet
Encapsulation
• L'encapsulation consiste à cacher l'état interne d'un objet et d'imposer de passer par des
méthodes permettant un accès sécurisé à l'état de l'objet.
• Pour mettre en œuvre l'encapsulation, la première étape consiste à privatiser les attributs.
• Ensuite, il faut fournir les méthodes d'accès sécurisées : appelées getters/setters en Java.
• Un getter permet l'accès en lecture à un attribut alors qu'un setter permet de demander
un changement d'état.
Encapsulation
• L'étape suivante consiste à rajouter les contrôles au niveau des setters : seul le
dénominateur nécessite une vérification.
Encapsulation
Encapsulation: portée des attributs
Type Mot-clé Description
Accessible depuis n’importe quel point de
Publique public
l’application
Accessible uniquement depuis les classes du même
Protégée protected
package et les classes filles
Accessible uniquement depuis les classes du même
Package
package
Accessible uniquement dans la classe de déclaration
Privée private
et les classes internes
Constructeur
• Un constructeur est une méthode qui se déclenche automatiquement lors de la
construction d'un objet.
• Malgré son nom, un constructeur ne se doit pas de construire, mais plutôt d'initialiser
l'objet.
• Dans certains autres langages de programmation orienté objet, le constructeur doit
s'appeler init ou encore initialize, voire __init__.
• Pour coder un constructeur, on doit respecter certaines règles:
Un constructeur ne doit pas spécifier de valeurs de retour, ni de void.
Un constructeur doit avoir, en Java, le même nom que la classe.
Constructeur
Surcharge de constructeurs
• Une classe peut contenir plusieurs constructeurs, autrement dit, on pourra produire des
objets de différentes manières.
• Cette possibilité, de définir plusieurs méthodes de même nom, mais de signatures
différentes s'appelle la surcharge.
Surcharge de constructeurs
Délégation de constructeurs
• C'est la capacité d’un constructeur à repasser la main à un autre constructeur plus
générique.
• La délégation s'obtient en utilisant le mot-clé this immédiatement suivi d'une paire de
parenthèses et des paramètres à passer à l'autre constructeur.
Affichage d’un objet Java
• En Java, il pourrait être intéressant de fournir directement dans une classe, une méthode
de génération de la chaîne de caractères associée à l'objet: toString().
Affichage d’un objet Java
• Maintenant si on écrit directement System.out.println( r ), r un objet de type Rational,
alors la méthode toString sera automatiquement invoquée.
Méthodes et attributs de classe
• Les méthodes et les attributs de classe appartiennent à une classe.
• Il est possible d’accéder à une méthode de classe (de même pour les attributs de classe)
par la classe dans laquelle la méthode a été déclarée ou par n’importe quelle classe qui en
hérite. Cependant, si l’attribut de classe est modifiable, sa valeur est partagée par
l’ensemble des classes qui font partie de la hiérarchie d’héritage.
Concept d’héritage
• L'héritage est un mécanisme qui facilite la réutilisation du code et la gestion de son
évolution.
• Elle définit une relation entre deux classes :
une classe mère ou super−classe, classe de base, classe parente
une classe fille ou sous−classe, classe dérivée qui hérite de sa classe mère
• En programmation orientée objet, il existe un formalisme graphique permettant de
représenter chaque concept « objet », UML(Unified Modeling Language), dans lequel:
Une classe se représente, en UML, avec une boîte rectangulaire divisée en un, deux ou
trois compartiments: nom de la classe, liste des attributs(facultatif), méthodes de l’objet
considéré.
Une relation d'héritage se représente avec une flèche avec une pointe triangulaire fermée.
La flèche doit partir de la classe dérivée et se dirige vers la classe de base.
Concept d’héritage
Concept d’héritage: classe mère
Concept d’héritage: classe mère
• Sin on veut empêcher les classes filles d’étendre la classe mère, il faut que cette dernière
soit déclarée final.
Concept d’héritage: classe fille
• En Java, pour mettre en œuvre l'héritage on utilise le mot-clé extends.
Concept d’héritage: classe fille
• Maintenant, on va ajouter les spécificités de la classe Client: le nom de l'entreprise où
il/elle travaille( attribut enterpriseName).
Concept d’héritage: classe fille
• L'étape suivante consiste également à rajouter un ou plusieurs constructeurs.
• Effectivement, la première chose que doit faire un constructeur c'est de redonner la main
au constructeur de la classe parente en utilisant l'instruction super.
• Cette instruction doit être utilisée en première instruction du constructeur enfant (on
commence par initialiser les attributs de la classe parente).
Concept d’héritage: Redéfinition de méthodes
• L‘intérêt de l’héritage est que nous pouvons utiliser l'intégralité des méthodes qui sont
définies dans les classes mère.
• Pour le cas de la méthode toString(), elle permet d'afficher une personne et donc un
client, mais le problème réside dans le fait qu'on ne sait pas afficher le nom de l'entreprise
avec cette méthode. C’est la raison pour laquelle on va la redéfinir pour l'enrichir au
niveau de la classe client.
• Pour redéfinir une méthode, on utilise l'annotation @Override au dessus de celle-ci.
Concept d’héritage: Redéfinition de méthodes
Héritage et Composition
• La composition est le type de relation le plus souvent utilisé en programmation objet. Elle
indique une dépendance entre deux classes.
• La relation est-un (is-a) permet de créer une chaîne de relation d’identité entre des
classes, c-à-d, une classe a besoin des services d’une autre classe pour réaliser sa fonction:
on parle de relation de composition (relation a-un ou has-a).
Héritage et Composition
Héritage et Composition
Polymorphisme
• Le polymorphisme est induit par l'héritage. Ce terme vient du grec ancien polús (plusieurs)
et morphê (forme).
• On parle de polymorphisme lorsqu’on a un ensemble hétérogène d'objets (basés sur les
classes Person, Client, Employee) partageant tous un point commun ( une personne). On
dit que cet ensemble contient, par polymorphisme, n'importe qu'elle instance basée sur
une classe dérivant de classe mère (Person).
Classe immuable (type record)
• Les records sont un nouveau type de classe dans le langage Java (record class), introduit
en standard en JSE 16.
• Une telle classe permet de produire des objets avec un état initial mais qui ne pourront
plus changer d'état une fois instanciés.
• Pour produire de tels objets, avant JSE 16, il fallait produire une classe réalisant une
encapsulation de ses membres (attributs privés) et n'exposant que les getters et surtout
pas les setters. Un certain volume de code était donc nécessaire pour produire une classe
d'instances immuables.
• Avec l'arrivée de JSE 16, l'apparition du concept de « record » rend les choses les plus
simples, une unique ligne de code permettant la définition d'une classe d'objets
immuables, donc de grosses économies de lignes de codes.
• Le concept de record était déjà présent dans quelques versions antérieures à JSE 16, mais
il faillait activer le support « Preview Features » au démarrage de la JVM pour y avoir
accès: > javac --enable-preview MyApp.java
Classe immuable: syntaxe traditionnelle
Classe immuable: syntaxe record
• L'exemple ci-dessous définit un record qui encapsule deux données : les coordonnées x et
y de manière immuable.
Classe immuable: syntaxe record
Classe immuable: syntaxe record
• Un type record est non extensible car il est défini comme final, donc on ne peut pas en
hériter.
• Un record peut implémenter une ou plusieurs interfaces.
• On peut, bien entendu, compléter un record avec de données membres, méthodes,
constructeurs, ...
Classes et méthodes abstraites
• L'héritage permet de factoriser un certains nombre de méthodes pour un ensemble de
types. Mais parfois, on aimerait factoriser un comportement sans que l'on soit en mesure
de l'implémenter: dans ce cas on va définir une ou plusieures méthodes abstraites.
Classes et méthodes abstraites
• En considérant l’exemple précédent, si on veut calculer l’aire de n’importe quelle figure
géométrique, alors on doit ajouter une méthode abstraite area() dans la classe Shape.
• L’implémentation de cette méthode sera à la charge de chaque sous-classe.
• Pour définir une méthode abstraite, il faut utiliser le mot-clé abstract devant la méthode :
public abstract double area();
• Si une classe contient au moins une méthode abstraite, alors elle doit être définie ainsi.
Classes et méthodes abstraites
• Une classe abstraite ne peut pas être instanciée car elle est considérée comme
incomplète.
• Elle sert à imposer la présence de méthodes dans les classes filles.
Concept d’interface
• Une interface est presque la même chose qu'une classe abstraite, sauf qu'une interface
contient, très souvent, que des méthodes abstraites.
• Une interface s'introduit via le mot-clé interface et elle peut contenir des méthodes qui
seront par défaut publiques et abstraites (pas nécessaire de spécifier les deux mots-clés
associés).
• Elle peut contenir des variables qui sont implicitement static et final.
Concept d’interface
• Même si elle ressemble à une classe abstraite, au lieu d'utiliser le mot-clé extends, on
utilisera le mot-clé implements dans les classes dérivées ( de même pour les classes
abstraites).
Concept d’interface
• Une interface peut être utilisée pour déclarer un type pour un objet: TeamType team;
• Une interface peut également hériter d’autres interfaces
• A partir de JSE 8.0. il est possible pour une interface de contenir des implémentations de
méthodes: ce sont des méthodes par défaut.
Concept d’interface
• En Java, l’héritage multiple n’est jamais autorisé: on ne peut dériver que d'une seule classe
mère. Par contre, on peut dériver d'une classe et implémenter une autre interface. Dans
ce cas l'implémentation d'interface sera obligatoirement placée après le lien d'héritage.
• De plus, on peut implémenter autant d'interfaces que souhaité en séparant leurs noms
avec des virgules.
Classe interne
• La plupart du temps, une classe en Java est déclarée dans un fichier portant le même nom
que la classe avec l’extension .java.
• Cependant, il est également possible de déclarer des classes dans une classe: on parle
alors de classes internes (inner classes). Cela est également possible pour les interfaces et
les énumérations.
• La déclaration des classes internes peut se faire dans l’ordre que l’on souhaite à l’intérieur
du bloc de déclaration de la classe englobante et elles peuvent être ou non
déclarées static.
Classe interne statique
• Les classes internes déclarées static sont des classes pour lesquelles l’espace de noms est
celui de la classe englobante:
Son nom complet inclut le nom de la classe englobante (comme un package):
com.guyzaho.ClasseEnglobante.ClasseInterne
La classe englobante et la classe interne partage le même espace privé: les attributs et les
méthodes privés déclarés dans la classe englobante sont accessibles à la classe interne et
réciproquement.
Une instance de la classe interne n’a accès directement qu’aux attributs et aux méthodes
de la classe englobante qui sont déclarés static.
• Une classe interne static est souvent utilisée pour éviter de séparer dans des fichiers
différents de petites classes utilitaires et ainsi de faciliter la lecture du code.
Classe interne statique
Classe interne non statique
• Comme pour les classes internes static, le nom complet de classe interne inclut celui de la
classe englobante et les deux classes partagent le même espace privé.
• Une classe interne maintient une référence implicite sur un objet de la classe englobante:
une instance d’une classe interne ne peut être créée que par un objet de classe
englobante : c’est-à-dire dans le corps d’une méthode ou dans le corps d’un constructeur
de la classe englobante.
une instance d’une classe interne a accès directement aux attributs de l’instance dans le
contexte où elle a été créée.
Expressions lambda
• Le fonctionnement des expressions lambda est spécifié dans la JSR 335 (Project Lambda)
faisant partie de la spécification JSE 8.0.
• En Java, une expression lambda est utilisée pour faciliter la vie en cas de besoin
d'implémentation d'une interface possédant une seule et unique méthode abstraite:
interface fonctionnelle. Elle simplifie la mise en œuvre d'une classe anonyme.
• Une interface fonctionnelle intègre une annotation permettant de les marquer:
(java.lang.FunctionalInterface). Par exemple, l'interface java.lang.Runnable souvent
utilisée par les Threads.
Expressions lambda: classe anonyme
• Une expression lambda permet de simplifier l’écriture d’une classe interne anonyme
(anonymous inner-classes) qui sont des classes internes qui ne possèdent pas de nom.
• Elles ne peuvent donc être instanciées qu'à l'endroit où elles sont définies.
• Ce type de classe est très pratique lorsqu'une classe doit être utilisée une seule fois : c'est
par exemple le cas d'une classe qui doit être utilisée comme un callback.
• Une syntaxe particulière de l'opérateur new permet de déclarer et instancier une classe
interne :
new classe_ou_interface () {
// définition des attributs et des méthodes de la classe interne
}
Expressions lambda: classe anonyme
• Exemple: les codes d’un gestionnaire d'événements pour le clic sur un bouton avant JSE 8.
Expressions lambda: classe anonyme
• Les codes précédents peuvent être réécrites avec une expression lambda de la façon
suivante.
Expressions lambda: syntaxe
• La syntaxe d'une expression lambda est composée de trois parties :
un ensemble de paramètres, d'aucun à plusieurs
l'opérateur ->
le corps de la fonction
• Elle peut prendre deux formes principales :
(paramètres) -> expression;
(paramètres) -> { traitements; }
• L'écriture d'une expression lambda doit respecter plusieurs règles générales :
zéro, un ou plusieurs paramètres dont le type peut être déclaré explicitement ou inféré
par le compilateur selon le contexte
les paramètres sont entourés par des parenthèses et séparés par des virgules. Des
parenthèses vides indiquent qu'il n'y a pas de paramètre
Expressions lambda: syntaxe
lorsqu'il n'y a qu'un seul paramètre et que son type est inféré alors les parenthèses ne
sont pas obligatoires
le corps de l'expression peut contenir zéro, une ou plusieurs instructions.
Si le corps ne contient d'une seule instruction, les accolades ne sont pas obligatoires et le
type de retour correspond à celui de l'instruction.
Lorsqu'il y a plusieurs instructions alors elles doivent être entourées avec des accolades
Références
• https://docs.oracle.com/javase/tutorial/index.html
• https://www.baeldung.com/get-started-with-java-series
• https://www.tutorialspoint.com/java/index.htm
• https://www.w3schools.com/java/
• https://java.developpez.com/cours/
• https://www.jmdoudoux.fr/accueil_java.htm