Vous êtes sur la page 1sur 35

Dan Garlasu, dgarlasu@yahoo.

com

1
Agenda
1. Introduction
2. Objects
3. Classes

2
 Programmation orientée objet : approche pour écrire des programmes en
représentant des entités du monde réel sous la forme d'objets logiciels
 Les objets représentent à la fois :
◦ attributs d'entités du monde réel et
◦ leur comportement
 L'état des attributs d'un objet peut être modifié en envoyant un message à
cet objet
 Tout le travail de calcul est accompli grâce à l'interaction entre les objets de
la collection - par des messages échangés entre les objets
 L'approche d’écrire de programmes informatiques orientée objet a constitué
un énorme progrès dans le développement des paradigmes de
programmation par rapport à l'approche de programmation procédurale.

Exemple:
- on peut représenter une voiture comme un objet.
attributs pour une voiture : … couleur, roues, équipement, freins, etc.
le comportement de la voiture peut être représenté au moyen de messages dits que l'objet
logiciel accepte : .. changer de vitesse, accélérer ou freiner.
Exemple:
imaginons que nous ayons un autre objet représentant une personne au volant de la voiture.
L'objet personne peut accélérer l'objet voiture en lui envoyant le message d'accélération.
Exemple:
dans la programmation procédurale, nous modélisons des entités du monde réel telles que
des voitures et des personnes au moyen de procédures et de séquences de leur exécution.
Cependant, cela semble une façon de penser et de modéliser des entités du monde réel plutôt
contre nature puisque les humains voient une voiture comme un objet avec un moteur, un
réservoir d'essence, quatre roues, etc. plutôt qu'une série de procédures qui la font
fonctionner.
De toute évidence, il est beaucoup plus naturel pour les humains de considérer les entités du
monde réel comme des objets dotés de certains attributs et comportements.

3
 Objets
 Messages
 Encapsulation
 Des classes
 Composition (Agrégation)
 Héritage (Spécialisation)
 Classes abstraites et interfaces
 Polymorphisme

Le diapo presente les concepts de base de la programmation orientée objet:

4
 Dans les programmes orientés objet, les objets sont conçus sur
des entités du monde réel - ils ont aussi des attributs, leur état
actuel et leur comportement:
◦ Les attributs sont représentés comme une ou plusieurs variables d'objet.
◦ Une variable est une donnée nommée par un identifiant. Les valeurs
actuelles des variables d'objet correspondent à l'état actuel de l'objet.
◦ L'objet implémente son comportement au moyen de soi-disant méthodes.
Une méthode est une procédure (fonction, sous-programme) associée à
un objet.
◦ Formellement, nous appelons des variables d'objet des variables
d'instance, et les méthodes d'objet sont formellement appelées des
méthodes d'instance.

Nous pouvons définir un objet comme un logiciel qui combine des variables, leurs
valeurs courantes et un certain nombre de méthodes.
Par exemple, nous pourrions représenter une voiture comme un objet qui a des
variables appelées boite d’engrenage, vitesse ou couleur.

Les valeurs de ces variables indiquent son état actuel : le rapport actuel
d’engrenage est le 4ème rapport ; la vitesse actuelle est de 100 km/h ; la couleur
est noire.

En plus des variables, l'objet voiture a des méthodes pour changer son état
actuel: pour freiner, accélérer ou changer la vitesse actuelle.

En règle générale, l'exécution d'une méthode entraîne la modification des valeurs


des variables d'objet.

5
 Parce que les objets singuliers ne sont pas très utiles,
un programme orienté objet se compose d'un certain
nombre d'objets, qui interagissent les uns avec les
autres en s'envoyant des soi-disant messages.
 Envoyer un message à un objet signifie invoquer
(appeler et exécuter) une méthode d'instance de cet
objet, c'est-à-dire qu'il s'agit simplement d'un appel de
fonction (procédure, sous-programme) tel que nous
avons vu aux programmes procéduraux.

Parfois, l'objet récepteur a besoin de plus d'informations pour exécuter sa


méthode. Par exemple, si l'objet voiture doit changer de vitesse, il doit savoir
quelle est la vitesse souhaitée. Techniquement, cela est accompli au moyen
d'arguments qui sont passés à une méthode d'instance.
En résumé, un message est composé des trois composants suivants :
• L'objet qui reçoit le message (l'objet voiture)
• Le nom de la méthode à exécuter (changeGear)
• Paramètres supplémentaires nécessaires pour exécuter la méthode (la 4ème
vitesse)

6
 L'emballage des variables d'un objet sous la garde protectrice de ses
méthodes s'appelle l'encapsulation des données
 Le concept d'encapsulation de données est l'un des concepts les plus
importants de l'approche de programmation orientée objet et présente un
certain nombre d'avantages :
◦ Modularité:
 Le code source d'un objet peut être écrit et maintenu indépendamment du code source d'autres
objets
◦ Cacher des informations:
 Un objet a une interface que d'autres objets peuvent utiliser pour interagir avec lui
◦ Réutilisation du code:
 Si un objet existe déjà (peut-être écrit par un autre développeur de logiciel), vous pouvez utiliser
cet objet dans votre programme
◦ Enfichabilité (Pluggability) et facilité de débogage:
 Si un objet particulier s'avère problématique, vous pouvez simplement le supprimer de votre
application et brancher un objet différent en remplacement.

Les valeurs courantes des variables d'instance constituent l'état courant d'un
objet. Ces variables d'instance sont internes ou privées à un objet. Les autres
objets d'un programme orienté objet ne peuvent pas accéder et manipuler
directement ces variables d'instance. La seule possibilité pour d'autres objets de
modifier l'état d'un objet est de lui envoyer des messages, c'est-à-dire d'invoquer
ses méthodes. Ainsi, l'état actuel d'un objet est caché aux autres objets. Il est
cependant entouré de ses méthodes qui fournissent une interface d'interaction
entre cet objet et d'autres objets. L'encapsulation des variables d'un objet sous la
garde protectrice de ses méthodes s'appelle l'encapsulation des données. Cela
signifie que l'objet reste maître de la façon dont le monde extérieur est autorisé à
l'utiliser en regroupant le code complet (variables d'instance et méthodes
d'instance) en interne en un seul endroit.

7
 Dans les programmes orientés objet, nous pouvons avoir un certain nombre d'objets du
même type, qui ont les mêmes variables d'instance et les mêmes méthodes d'instance
 Pour modéliser cette situation dans les programmes orientés objet, les programmeurs
définissent ce que l'on appelle des classes.
 Une classe peut être considérée comme un prototype ou modèle qui définit des variables
d'instance et des méthodes d'instance communes à tous les objets du même type.
 Définir une classe dans un logiciel orienté objet signifie écrire un morceau de code source
qui déclare des variables d'instance et déclare et implémente des méthodes d'instance
pour cette classe d'objets
 Interface de classe - répertorie tous les messages que les objets de cette classe acceptent
 Les variables d'objet sont appelées variables d'instance
 Les méthodes d'objet sont appelées méthodes d'instance
 Les objets d'une classe sont généralement appelés instances de classe

Il existe des entités du monde réel qui sont très souvent similaires les unes aux
autres, c'est-à-dire qu'elles sont de la même nature. Par exemple, une voiture
noire et une voiture blanche sont similaires l'une à l'autre - elles sont toutes les
deux du même type, c'est-à-dire qu'elles sont toutes les deux des voitures. Ils ne
diffèrent que par la couleur, c'est-à-dire qu'ils ne diffèrent que par un seul aspect
de leur état actuel. Cependant, les attributs et le comportement sont les mêmes
dans les deux cas.
Par exemple, une classe de voiture peut définir :
• Variables d'instance telles que l'équipement, la vitesse, la couleur, etc.
• Les méthodes d'instance nécessaires pour modifier l'état d'objets particuliers
appartenant à la classe de voiture. Ainsi, des méthodes telles que
changeGear, break ou accélération peuvent être définies.

8
 La programmation orientée objet permet aux programmeurs de
suivre la même approche de composition (agrégation).
 Ainsi, il est possible de créer des objets plus complexes en
combinant des objets déjà existants (plus simples) en un
nouveau.
 Techniquement, une classe définissant de tels objets complexes
ou composites, a comme variables d'instance d'autres objets
 Le principe de composition facilite beaucoup la réutilisation des
composants logiciels

Habituellement, ces entités complexes sont composées d'un (éventuellement)


grand nombre d'entités plus simples. Par exemple, une voiture est composée de
(au moins) :
• Un moteur -> objet moteur
• Un cadre -> objet cadre
• Une carrosserie -> objet carrosserie
• Suspension
• Pauses
• roues
L'objet voiture peut être vu comme une composition d'un certain nombre d'autres
objets plus simples

9
 Les cas particuliers d'une classe peuvent être définis à travers le concept de sous-
classement (spécialisation)
 Le cas particulier d'une classe est appelé sous-classe
 La classe d’origine est appelée superclasse
 Chaque sous-classe hérite des propriétés de sa super-classe
◦ Variables d'instance
◦ Méthodes d'instance
 Les sous-classes peuvent ajouter des variables et des méthodes à celles héritées de la
super-classe
 Les sous-classes peuvent également remplacer les méthodes d'instance héritées et
fournir des implémentations spécialisées pour ces méthodes
 La hiérarchie des classes (arbre d'héritage) peut être aussi profonde que nécessaire. Les
méthodes d'instance et les variables sont héritées via les niveaux de l'arborescence. En
général, plus une classe apparaît bas dans la hiérarchie, plus elle possède un
comportement et des attributs plus spécialisés.

Par exemple: la classe de voiture de notre exemple serait une superclasse avec des sous-classes telles que :
• Classe de voiture de sport
• Classe de voiture de tourisme
• Classe de camion, et ainsi de suite
chaque sous-classe hérite des propriétés de sa super-classe. Ceci comprend:
• Variables d'instance - les voitures de sport, les camions et les voitures de tourisme partagent les mêmes
variables d'instance : vitesse, vitesse, etc.
• Méthodes d'instance - encore une fois, les voitures de sport, les camions et les voitures particulières
partagent le même comportement : freinage et changement de vitesse,
Par exemple, les voitures de sport ont deux sièges et 6 vitesses, les camions ont une remorque, etc. Ces
attributs et tous les comportements supplémentaires peuvent être reflétés par les sous-classes.
Semblable au principe de composition, le principe d'héritage prend en charge la réutilisation des composants
logiciels. Cependant, avec l'héritage, on réutilise principalement l'interface de la superclasse, alors qu'avec la
composition, nous réutilisons les fonctionnalités fournies par les composants. La sous-classe a la même
interface que la super-classe, ainsi ses instances peuvent recevoir les mêmes messages que sa super-classe

10
 Une classe abstraite définit uniquement un comportement
"générique".
 Une telle classe abstraite définit une interface dite abstraite et peut
implémenter partiellement les méthodes d'instance de cette interface
 Les classes abstraites déclarent une ou plusieurs méthodes en tant
que méthodes abstraites. Lorsque la classe est héritée, la sous-
classe doit implémenter toutes les méthodes abstraites ou la sous-
classe est également considérée comme abstraite. Il n'est pas
possible de créer des instances de classes abstraites
 Un autre concept similaire est le concept d'interface. Vous pouvez
considérer une interface comme une classe abstraite avec toutes les
méthodes déclarées comme abstraites

Exemple pour illustrer l'utilisation des classes abstraites.


Dans une application de dessin orientée objet, nous pouvons dessiner des cercles, des
rectangles ou des lignes. Ces objets ont tous en commun certains attributs tels que la
position, l'orientation, la couleur de ligne, la couleur de remplissage et certains
comportements tels que le déplacement, la rotation, le redimensionnement ou le dessin.
Certains de ces attributs et comportements sont les mêmes pour tous les objets
graphiques, par ex. positionner, remplir la couleur ou déplacer. D'autres nécessitent des
implémentations différentes, par ex. redimensionner ou dessiner.
Tous les objets doivent savoir se dessiner ou se redimensionner ; ils diffèrent juste dans
la façon dont ils le font. C'est une situation parfaite pour une superclasse abstraite. Nous
pouvons tirer parti des similitudes et déclarer que tous les objets graphiques héritent de
la même superclasse abstraite qui implémente toutes les méthodes d'instance
courantes.
Cependant, chaque sous-classe particulière devra implémenter son comportement
spécifique, implémentant ainsi des méthodes d'instance abstraites telles que draw ou
resize.

11
 Tout le principe des objets interchangeables s'appelle le
polymorphisme
 Pour démontrer le polymorphisme, nous écrirons un seul morceau
de code qui ignore les détails spécifiques des sous-classes et ne
parle qu'à la classe de base. Nous dissocions ce code des
informations spécifiques à la sous-classe, et ainsi le code est plus
simple à écrire et plus facile à comprendre
 Si nous ajoutons une nouvelle classe, par héritage, le code que
nous écrivons fonctionnera aussi bien pour la nouvelle classe que
pour les classes existantes. Ainsi, le programme devient extensible

Exemple:
un objet conducteur envoie un message à un objet voiture quel que soit le type spécifique de
cette voiture. Le conducteur peut accélérer, freiner ou changer de vitesse l'objet voiture sans
savoir si cette voiture est une voiture de sport, un camion, une voiture de tourisme ou même
une instance d'un type de voiture qui n'est pas encore défini. Cela permet aux programmeurs
d'écrire du code qui ne dépend pas d'une sous-classe spécifique. Au contraire, ce code
dépend uniquement de la superclasse de voiture générique.
Cependant, il y a un problème avec la tentative de traiter les instances d'une sous-classe
comme des instances de sa super-classe. Techniquement, au moment de l'exécution, l'objet
conducteur envoie un message à une instance d'une sous-classe spécifique, c'est-à-dire que
le conducteur dirige une voiture de sport, un camion ou une voiture de tourisme.
Ainsi, le système doit déléguer un message de l'objet conducteur, qui est envoyé à une
instance de la superclasse de voiture à une instance de la sous-classe appropriée.
Pour y parvenir, les systèmes orientés objet ne lient pas un appel à une méthode spécifique
au moment de la compilation, mais ils le font plutôt au moment de l'exécution lorsque l'identité
réelle des objets est connue.

12
 Du point de vue de la conception, la programmation orientée objet
concerne uniquement le typage abstrait des données, l'héritage et
le polymorphisme, mais d'autres problèmes plus techniques
peuvent être au moins, aussi importants :
◦ La façon dont les objets sont créés et détruits
◦ Où sont stockées les données d'un objet ?
 Il existe plusieurs approches différentes pour contrôler ces
problèmes :
◦ Des approches qui favorisent l'efficacité
◦ Approches qui favorisent la flexibilité
 De tels problèmes et la manière dont ils sont résolus influencent
fortement un soi-disant cycle de vie des objets

Pour prendre en charge l'efficacité, le stockage et la durée de vie des objets peuvent être
déterminés lors de l'écriture du programme. Ainsi, les programmeurs peuvent choisir de
placer des objets sur la pile, des registres, etc. Les langages de programmation tels que
C++ prennent en charge cette approche. Une telle approche fournit une vitesse
d'exécution maximale, mais au détriment de la flexibilité. Le programmeur doit connaître
la quantité exacte, la durée de vie et le type d'objets pendant l'écriture du programme.
Afin de prendre en charge la flexibilité, les objets peuvent être créés dynamiquement
dans un pool de mémoire appelé tas. Dans ce cas, le programmeur n'a pas besoin de
connaître au moment de l'écriture du programme la quantité exacte, la durée de vie ou le
type d'objets. Cette approche est assez flexible, bien que beaucoup plus lente que la
première approche car le système doit gérer la mémoire de tas - dynamiquement et au
moment de l'exécution. Les langages de programmation tels que Java prennent en
charge cette approche.
Différence entre Heap et Stack - la façon dont vous y accédez. La pile n'est accessible
que par un côté (le haut). Pour accéder à Heap, voir AHO & Ullman page 280.

13
 Pour créer un objet, le nouveau mot clé est utilisé pour créer une
instance de cet objet dans la mémoire du tas (heap memory),
c'est-à-dire pour allouer dynamiquement suffisamment de
mémoire du tas pour stocker toutes les variables d'instance
 ‘Garbage collector’ découvre automatiquement quand un objet
n'est plus utilisé, et le détruit
 En Java, il n'est pas nécessaire de détruire explicitement une
instance d'une classe. Au lieu de cela, le système prend soin de
tous les objets qui ne sont plus utilisés en les détruisant et en
libérant la mémoire que ces objets ont allouée

La plate-forme Java permet aux programmeurs de créer autant d'objets qu'ils le


souhaitent (limités, bien sûr, par ce que votre système peut gérer), et ils n'ont pas
à se soucier de les détruire. L'environnement d'exécution Java supprime les
objets lorsqu'il détermine qu'ils ne sont plus utilisés. Ce processus s'appelle… la
collecte des ordures.
Un objet est éligible pour la récupération de place… lorsqu'il n'y a plus de
références à cet objet, c'est-à-dire lorsqu'il ne reste plus de variables contenant
au moins une référence à l'objet. Une référence est généralement supprimée
lorsque la variable qui la contient sort de la portée. Les programmeurs peuvent
supprimer explicitement une référence d'objet en… définissant la variable sur la
valeur spéciale null. N'oubliez pas qu'un programme peut avoir plusieurs
références au même objet ; toutes les références à un objet doivent être
supprimées avant que l'objet soit éligible pour la récupération de place.

14
 Une classe fournit un prototype pour créer des objets; on crée
ainsi des objets ou des instances de classes
 La création d'objets comprend les trois parties fondamentales:
1. Déclaration de variable - elle associe un nom à un type
2. Instanciation - l'opérateur new, crée un nouvel objet, c'est-à-dire
qu'il lui alloue dynamiquement de l'espace mémoire
3. Initialisation - le nouvel opérateur est suivi de l'appel à un
constructeur, qui initialise l'objet nouvellement créé

Example:
Point origin = new Point (100, 100);
Circle circle = new Circle (origin, 50);
Rectangle rectangle = new Rectangle (origin, 80, 50);

Pour déclarer une variable on écrit : Type name


Ainsi, nous utiliserons name pour faire référence à une variable, dont le type est Type. Dans
l'exemple ci-dessus, la partie du code en gras déclare des variables :
Notez qu'une déclaration de variable ne crée pas encore d'objet - elle déclare simplement une
variable avec ce nom et ce type. La variable fera référence à un objet, une fois que cet objet
est créé, c'est-à-dire que les variables en Java d'un type de données non primitif (par exemple
un objet d'une classe particulière) sont techniquement des références et qu'elles conservent
des adresses de mémoire où un objet particulier est stocké .
L'instanciation est effectuée au moyen de l’opérateur new. L’opérateur new crée une instance
d'une classe en allouant de la mémoire pour ce nouvel objet. Il nécessite un seul argument
postfixé : un appel à un constructeur. Le nom du constructeur correspond au nom de la classe
à instancier. Le constructeur initialise le nouvel objet.
L'opérateur new renvoie une référence à l'objet qui a été créé et cette référence est affectée à
une variable du type approprié.
Le constructeur lui-même implémente l'initialisation des variables d'instance avec les valeurs
qui lui sont fournies en affectant les valeurs passées aux variables d'instance.

15
 Une fois créés, les objets sont utilisés pour effectuer différentes tâches :
◦ Manipuler et inspecter ses variables
◦ Appel de ses méthodes
 Pour accéder à la variable d'un objet en Java on écrit :
object_reference.variable_name
 object_reference, doit être une référence à un objet
 variable_name, est le nom valide d'une variable d'instance de cet objet
 Java fournit un mécanisme dit de contrôle d'accès pour contrôler l'accès à
ses variables
 Ainsi, les variables peuvent être déclarées comme :
◦ Publique,
◦ privé ou
◦ protégé

Afin d'accéder aux variables des objets de la manière présentée ci-dessus, ces variables d'instance doivent
être déclarées comme étant des variables publiques. Cependant, déclarer une variable d'instance
publique est fortement déconseillé. Cela entrave le principe d'encapsulation des données, c'est-à-dire
que les variables d'instance ne sont pas encapsulées dans un objet. De tels objets permettent une
manipulation directe de leurs variables d'instance, au lieu de fournir des méthodes permettant de manipuler
leurs variables d'instance, mettant ainsi en danger les principes de base de l'orientation objet. Par
exemple… la modularité du code n'est plus garantie puisqu'il peut y avoir du code en dehors du code de
l'objet qui manipule ses variables d'instance, c'est-à-dire que le code de l'objet n'est plus autonome et
modulaire.

En règle générale, toutes les variables d'instance doivent être déclarées comme privées ou protégées. La
seule situation où le modificateur d'accès public peut être utilisé est de déclarer une… constante.
La différence entre privé et protégé est la suivante… les variables d'instance privées ne sont visibles que
pour les instances de cette classe particulière ; les variables d'instance protégées sont visibles pour les
instances de la classe en question et pour les instances de toutes les sous-classes de cette classe
particulière.

16
 Pour appeler une méthode publique d'un objet en Java on écrit :
object_reference.methodName (arguments_list);
 Si la méthode ne prend aucun argument on écrit :
object_reference.methodName ();
 Tout objet peut invoquer une méthode publique d'un objet particulier
◦ Parfois, une classe doit restreindre l'accès aux méthodes de ses instances - dans ce
cas, la méthode est déclarée comme protégée
◦ De même, si seules les instances de la classe en question sont censées appeler une
méthode particulière, le modificateur d'accès pour cette méthode doit être déclaré
comme privé
 Example:
circle.move (new Point (100, 50));
circle.scale (0.5);

Par exemple, imaginez que la classe Circle ci-dessus fournit les deux méthodes
publiques suivantes :
• La méthode Move pour modifier l'origine d'un cercle ; comme argument
cette méthode prend un objet Point qui devient la nouvelle origine de ce
cercle
• La méthode Scale pour modifier le rayon d'un cercle ; comme argument
cette méthode prend un nombre réel qui détermine le facteur d'échelle.

Notez qu'appeler une méthode d'un objet équivaut à envoyer un message à cet
objet.
Parfois, les méthodes renvoient des valeurs. Par exemple, imaginez une
méthode de la classe Circle, qui calcule l'aire d'un cercle particulier. Évidemment,
une telle méthode renverrait un nombre réel.
double circle_area = cercle.getArea ();

17
 Dans un programme orienté objet, au moment de l'exécution, le
nombre d'objets peut devenir très grand
 Un mécanisme particulier de stockage et de gestion des objets
dépend du type d'objets, ainsi que du nombre d'objets créés.
 Très souvent, nous stockons des objets dans :
◦ Tableaux
◦ Collections
 Pour un accès facile et rapide aux objets disponibles, les soi-
disant itérateurs sont généralement facilités

L’itérateur este presente au diapo no. 24.

18
 Un tableau est…
◦ une structure (de longueur fixe) qui contient un nombre fixe de
valeurs du même type
 la longueur du tableau doit être spécifiée lors de sa
création. Pour créer un tableau…
◦ utiliser l’opérateur new, ou…
◦ utiliser un initialiseur de tableau.
 Une fois créé, la taille du tableau ne peut pas changer.
Pour obtenir la longueur du tableau…
◦ utilisez l'attribut de longueur length.

Un élément de tableau est l'une des valeurs d'un tableau et est accessible par sa
position dans le tableau.
String[] array = { "String One", "String Two", "String Three" };
L'expression ci-dessus crée un tableau String avec trois éléments.

Pour accéder aux éléments de ce tableau, nous écrirons quelque chose comme
ceci:
for (int i = 0; i < array.length; i++) {
System.out.println(array[i].toLowerCase());}
Le code en caractères gras accède au i-ème élément du tableau. Ainsi, un élément
d'un tableau est accessible par son index. Les indices commencent à 0 et se
terminent à la longueur du tableau moins 1.
Le code en caractères gras obtient la longueur d'un tableau:
for (int i = 0; i < array.length; i++) {
System.out.println(array[i].toLowerCase());}

19
 Représente l'une des valeurs d'un tableau et est accessible par sa position
dans le tableau
String[] array = { "String One", "String Two", "String Three" };
 L'expression ci-dessus crée un tableau String avec trois éléments
 Pour accéder aux éléments de ce tableau, nous écrivons:
for (int i = 0; i < array.length; i++) {
System.out.println(array[i].toLowerCase());}
 Le code en caractères gras accède au i-ème élément du tableau.
 Ainsi, un élément d'un tableau est accessible par son index. Les indices commencent à 0 et se
terminent à la longueur du tableau moins 1.
 Le code en caractères gras obtient la longueur d'un tableau :
for (int i = 0; i < array.length; i++) {
System.out.println(array[i].toLowerCase());}

20
 Si nous voulons stocker des données de différents types
dans une seule structure, ou si nous avons besoin d'une
structure avec une longueur non fixe, nous utilisons une
implémentation de collection au lieu d'un tableau.
 Généralement, une collection est un objet qui contient des
références à d'autres objets.
 Chaque bon langage de programmation orienté objet est
livré avec un ensemble de différentes implémentations de
classes de collection dans sa bibliothèque

Java a également des collections dans sa bibliothèque standard. De plus, la


bibliothèque Java a différents types de collections pour différents besoins : un vecteur
(appelé ArrayList en Java) pour un accès cohérent à tous les éléments, et une liste
chaînée pour une insertion cohérente des éléments, etc. Ainsi, le programmeur peut
choisir le type particulier qui correspond à ses besoins.

21
 Nous utilisons ArrayList comme exemple de collections en Java :
List list = new ArrayList();
list.add(“dog”);
list.add(“cat”);
list.add(new Integer(10));
 Il existe un certain nombre d'autres méthodes prises en charge par la classe
ArrayList que nous pouvons utiliser pour ajouter un élément à une instance
de cet objet. Par exemple, si nous voulons insérer un objet dans une liste à
une position spécifique, nous écrivons:
list.set(1, new Rectangle(new Point(0, 10), 100, 50));
 Pour accéder à un objet d'une liste, on écrit le code suivant :
Rectangle rect = (Rectangle) list.get(1);

La première expression crée un objet ArrayList vide. Les trois instructions


suivantes ajoutent des objets à l'objet liste. Les deux premiers objets sont des
objets String, tandis que le troisième objet est une instance de la classe Integer.

Pour le deuxième exemple, l'expression insère une instance de la classe


Rectangle à la deuxième position dans la liste. Notez que les indices de liste
commencent également à 0, comme c'est le cas avec les tableaux en Java.

22
 Étant donné que les collections peuvent contenir n'importe quel type d'objets,
nous devons convertir l'objet renvoyé en son type réel
 Il s'agit d'un inconvénient connu de tous les objets de collection: le type
d'objets qu'ils contiennent est inconnu des collections, c'est-à-dire qu'une fois
que vous avez placé vos objets dans une collection, leur type est "perdu".
Tout ce que l'on sait d'une collection, c'est qu'elle contient des objets (de tout
type)
 Les collections prennent également en charge la suppression des objets
qu'elles détiennent
 Inconvénient : il faut connaître le type exact de la collection pour pouvoir
l'utiliser
 Afin de pallier cet inconvénient, nous appliquons le concept de iterateur

Les collections prennent également en charge la suppression des objets qu'elles


contiennent. Par example:
list.remove(1);
L'instruction ci-dessus supprime le deuxième élément de la liste.
Dans l'exemple de liste ci-dessus, nous avons vu comment utiliser un objet ArrayList
pour stocker des objets. Cependant, Java propose un certain nombre d'autres classes
de collection, telles que:
• LinkedList,
• HashSet,
et ainsi de suite que nous pouvons également utiliser pour stocker des objets.
Évidemment, chacune de ces classes de collection fournit une interface publique
spécifique avec un ensemble de méthodes différentes pour manipuler les éléments de
la collection.
Cependant, il y a un inconvénient à cela - nous devons connaître le type exact de la
collection afin de l'utiliser. Afin de pallier cet inconvénient, nous appliquons le concept
de iterator

23
 Un itérateur est un objet qui peut se déplacer dans une séquence
(de n'importe quel type) d'objets et sélectionner chaque objet dans
cette séquence.
 Le programmeur n'a pas besoin de connaître ou de se soucier de
la structure sous-jacente de cette séquence
 Toutes les classes de collection en Java fournissent des méthodes
pour obtenir différents itérateurs standardisés
Example:
Iterator iterator = list.iterator();
while(iterator.hasNext())
iterator.next().toString();

Tout d'abord, nous demandons à un objet liste un objet itérateur. Une fois que
l'objet itérateur est obtenu, il peut être utilisé pour parcourir les éléments d'une
liste particulière (le code en gras).

24
 Examinons le code suivant pour voir les avantages de
l'approche itérative.
 Supposons que nous ayons créé au préalable une instance
de la classe HashSet nommée hash :
Iterator iterator = hash.iterator();
while(iterator.hasNext())
iterator.next().toString();
 Ainsi, le même code est utilisé que pour l'objet liste.

25
 Tous les objets en Java sont du même type, car toutes les classes en Java
sont des sous-classes d'une seule classe de base.
 En Java, le nom de cette classe de base ultime est simplement Object
 Une telle hiérarchie de classes est appelée hiérarchie à racine unique
 Les avantages de la hiérarchie à racine unique:
 Tous les objets ont une interface en commun, ils sont donc tous finalement du même
type.
 Tous les objets peuvent être garantis pour avoir certaines fonctionnalités.
 Une hiérarchie à racine unique facilite grandement l'implémentation d'un ramasse-
miettes (qui est commodément intégré à Java).
 Étant donné que les informations de type à l'exécution sont garanties dans tous les
objets, vous ne vous retrouverez jamais avec un objet dont vous ne pouvez pas
déterminer le type.

Nous avons mentionné précédemment que les collections conservent des


objets de tout type. En interne, les collections conservent un tableau d'objets
qui peuvent être de types différents.

Cependant, les tableaux en Java ne contiennent que des objets d'un seul
type. Il est possible que les collections conservent des objets de différents
types si elles conservent un tableau d'objets à l'aide de la hiérarchie à routage
unique.

Par exemple, la classe Object définit la méthode toString utilisée pour


imprimer un objet. Avec une hiérarchie à racine unique, tout objet Java peut
être imprimé au moyen de la méthode toString.

26
 Une définition de classe :
◦ Déclare un certain nombre de variables d'instance
◦ Définit un certain nombre de méthodes publiques utilisées pour manipuler les variables
d'instance
 La première chose par laquelle chaque définition de classe commence est…
◦ la déclaration de la classe:
public class Stack{
// class definition
// ….
}
 Le code en carcteres gras déclare une classe publique avec le nom Stack.
La classe publique signifie que d'autres classes, soit pour l'héritage, soit pour
la composition, peuvent utiliser cette classe.

Nous avons appris à créer, détruire et utiliser des objets. Il est maintenant temps de
voir comment créer des définitions de classe, que nous utilisons comme prototypes
pour les objets.

En plus de cela, une définition de classe peut également définir un certain nombre de
soi-disant constructeurs, qui sont utilisés pour initialiser les instances de cette classe,
au moment de la création. Certains langages de programmation orientés objet, tels que
C++, exigent des programmeurs qu'ils définissent également des destructeurs, qui sont
utilisés pour libérer la mémoire occupée par les objets. Cependant, le ramasse-miettes
en Java s'occupe du nettoyage des objets, il n'y a donc pas de définitions de
destructeur requises en Java.

Une définition de classe suit une déclaration de classe dans un corps de classe. Ainsi,
un corps de classe déclare des variables d'instance ; méthodes de manipulation des
variables d'instance et peuvent en outre définir des constructeurs.
Si une définition de classe ne définit pas de constructeur, Java fournit à cette classe un
constructeur public vide par défaut.

27
 Pour déclarer une variable d'instance :
public class Stack{
private ArrayList items_;
// ….
}
 Le code en gras déclare une seule variable d'instance dans la classe Stack. Notez que
cette déclaration commence par le modificateur d'accès privé pour encapsuler la variable
d'instance.
 En déclarant une variable d'instance comme étant privée, nous interdisons aux objets
d'autres classes d'accéder directement à cette variable, permettant ainsi à d'autres objets
de manipuler cette variable d'instance uniquement par les méthodes d'instance.
 Déclarer une variable d'instance comme privée interdit également aux objets des sous-
classes d'accéder directement à cette variable d'instance particulière

Il est parfois plus pratique d'autoriser les sous-classes à accéder directement aux variables d'instance
de leur super-classe. Le modificateur d'accès protégé prend en charge cette situation.
Enfin, une variable d'instance peut être déclarée publique, mais comme indiqué ci-dessus, cela nuit
gravement au principe d'encapsulation et est fortement déconseillé. Dans des cas particuliers où une
variable d'instance est en fait une constante, le modificateur d'accès public peut être utilisé :
Public class math {
public final static double PI = 3.14;
// …
}
Notez que la variable PI est également déclarée comme final et statique, ce qui la rend constante
(final garantit qu'aucune nouvelle valeur ne peut être attribuée à cette variable, et static déclare cette
variable comme une variable dite de classe disponible pour toutes les instances de la classe –
techniquement, cela signifie qu'il n'y a qu'une seule adresse mémoire stockant cette variable pour
toutes les instances de la classe). Pour accéder à cette constante, nous pouvons écrire quelque
chose comme ceci :
double area = radius * radius * Math.PI;

28
 Lorsque nous déclarons une variable d'instance, nous
pouvons également l'initialiser à une certaine valeur
 Si nous ne fournissons pas de valeur lorsque nous
déclarons une variable d'instance, alors cette variable
d'instance obtient une valeur par défaut. Java a des
valeurs par défaut pour chaque type primitif, ainsi que pour
les références d'objet
 L'autre façon d'initialiser les variables d'instance consiste à
implémenter des constructeurs. Les constructeurs
prennent des arguments, nous pouvons donc initialiser des
variables d'instance avec des valeurs paramétrées

Voici le tableau des valeurs par défaut des variables en Java :…


Boolean – false
Byte - (byte)0
Short - (short)0
int – 0
Long – 0L
Float – 0.0f
Double – 0.0d
Reference –null

29
 Les classes définissent des méthodes pour manipuler leurs
variables d'instance. Cela signifie qu'une classe fournit une
déclaration de méthode, c'est-à-dire qu'elle déclare :
◦ le nom de la méthode
◦ son modificateur d'accès
◦ ses arguments et
◦ ses valeurs de retour
 En plus de cela, une classe implémente le corps de la
méthode, c'est-à-dire qu'elle fournit une définition complète
de ses méthodes d'instance

Parfois, lorsqu'une méthode est déclarée abstraite et que, par conséquent, toute la classe est déclarée
abstraite, la classe déclare simplement la méthode et ne fournit pas le corps de la méthode, c'est-à-dire
qu'elle ne l'implémente pas. Dans ce cas, les sous-classes d'une classe abstraite sont censées fournir cette
implémentation.
Dans le cas où des méthodes sont déclarées publiques, cela signifie que des objets d'autres classes
pourraient invoquer ces méthodes, ils peuvent envoyer ces messages aux instances de la classe Stack.
Ainsi, la classe Stack fournit une interface publique, qui est le point d'accès unique lorsque d'autres objets
veulent manipuler ses variables d'instance. Cela suit les principes de base orientés objet décrits ci-dessus.
Cependant, il existe des situations où une classe souhaite restreindre l'accès à ses méthodes, les déclarant
ainsi protégées ou privées. Cela peut être le cas chaque fois qu'une méthode est utilisée uniquement pour
une manipulation interne des données. La différence entre protégé et privé est… la même que pour les
variables d'instance. Par conséquent, une méthode privée n'est accessible qu'à partir des instances de la
classe elle-même, alors qu'une méthode protégée peut également être accessible à partir des instances de
toutes les sous-classes.
La prochaine chose importante dans une déclaration de méthode est la déclaration de la valeur de retour. Si
la méthode ne renvoie pas de valeur, nous la déclarons nulle comme dans le cas de la méthode push.
Sinon, nous déclarons une méthode pour renvoyer une valeur d'un certain type, comme Object dans le cas
de la méthode pop ou boolean dans le cas de la méthode isEmpty.
Enfin, nous fournissons le nom d'une méthode et listons tous les arguments qu'une méthode prend. Par
exemple, dans le cas de la méthode push, nous prenons un argument de type Object, alors que les deux
méthodes restantes (boolean, isEmpty) ne prennent aucun argument.

30
 Le corps de la méthode fournit une implémentation particulière.
◦ Notez que cette implémentation est cachée de tous les autres objets.
 Tout ce que les autres objets connaissent des instances d'une classe
particulière est leur interface publique. Ils ne connaissent pas et ne sont
en fait pas intéressés par une implémentation particulière fournie par une
classe - cela soutient grandement la modularité dans les programmes
orientés objet.
 De plus, une implémentation particulière peut être facilement remplacée
par, disons, une implémentation plus efficace, tant que l'interface est
satisfaite et que les résultats attendus restent les mêmes qu'auparavant

31
 La dernière partie couverte par une définition de classe est la définition des
constructeurs
 Nous définissons des constructeurs afin de fournir une initialisation
paramétrée des instances d'une classe
 Si nous n'avons pas besoin d'initialisation paramétrée, nous pouvons créer
une définition de classe sans définir de constructeurs. Dans ce cas
particulier, Java fournit un soi-disant constructeur vide par défaut
 En général, les constructeurs ont les propriétés suivantes :
◦ Modificateurs d'accès (public, privé, protégé) similaires aux variables d'instance et aux
méthodes
◦ Le nom d'un constructeur est le même que le nom de la classe
◦ Les constructeurs n'ont pas de valeurs de retour
◦ Les constructeurs peuvent prendre des arguments

32
33
34
35

Vous aimerez peut-être aussi