2- Principes de la programmation objet


1 Des classes et des objets

2 Hiérarchie d'objets


1 Des classes et des objets

(Ce qui suit sera repris et largement développé progressivement dans la suite du cours)

Notions

La notion de classe renvoie à un comportement générique. Elle est composée d'un ensemble d'attributs et de méthodes.

Par exemple, soit une classe Action, on peut envisager les attributs : nom, code, valeur. On peut envisager les méthodes : calculerLaRentabilite(), actualiserLeCours(), etc...

Un objet est l'instance d'une classe. L'instanciation vaut création d'objet. Dans un programme de gestion boursière, on utilise la classe Action pour laquelle on crée les instances/objets societeGenerale, bnp etc...

A tout moment, un certain nombre de classes sont actives. Pour ces classes, il est possible d'instancier des objets et de déclarer des variables qui référencent les objets créer.

Que sont les objets ?

Une classe définit un certain nombre de comportements ou méthodes (qui correspondent aux procédures et aux fonctions) et d'attributs (ou variables). Les attributs peuvent être des types primitifs (int, double, char etc...) ou des types-objets. Les objets peuvent être de différentes natures : Le tableau suivant donne l'exemple de méthodes et d'attributs pour les différents cas recensés. Les attributs d'objet peuvent être soit de type primitif : entier, réel etc... Soit des objets : un objet Facture peut référencer un objet Client par exemple.

Exemple d'objetAttributs possiblesMéthodes possibles
Facture
  • Un attribut réel montant
  • un attribut remise
  • un attribut objet Date
  • un attribut Objet Client
  • Une méthode impression()
  • une méthode affichage()
  • une méthode de création de fichier correspondant avec le chemin en attribut : exportToFile(String nomFichier)
Flux sur fichier
  • L'attribut chemin qui renseigne le point d'accès du fichier
  • La méthode ecrireTexte(Sting text) qui ajoute du texte
  • la méthode close() qui ferme le flux
Collection d'objets
  • Un attribut de taille de la collection
  • Une méthode d'ajout d'élements
  • une méthode pour vider la liste
Historique du cours
  • Un attribut de collection (éventuellement indexée) des cours d'un titre
  • Les méthodes : récupérer le cours d'une date particulière, établir une moyenne mobile de telle à telle date etc...


Les objets peuvent autant être des représentations limitées à l'application qu'ils peuvent également être des représentations/interfaces. Soit par exemple un objet Facture, on peut ne l'utiliser que dans le cadre de l'application ou bien, il est possible de faire en sorte qu'initialement les données soient récupérées sur un système d'information (XML, base de données relationnelles, web service etc...) et qu'ensuite les modifications sur l'objets entrainent des modifications dans le système d'information lié à l'objet. L'objet est alors représentation et interface. On pourrait aussi penser à des objets induisant des comportements d'impression. Les flux sur les fichiers sont typiquement à la fois des des objets et l'application et une interface de manipulation de la mémoire du disque dur.

Les objets et la mémoire vive

Quand on déclare une variable objet, on réserve un espace en mémoire vive qui va contenir l'adresse d'un objet. Quand on instancie un objet, on crée un espace en mémoire vive dans lequel on stocke l'objet. En affectant une nouvelle instance de classe à une variable objet, on met dans la variable objet l'adresse de l'objet nouvellement créé.





Type primitif

On déclare une variable entière :
	int i;
	

En mémoire vive sont reservés 4 octets. Imaginons qu'il s'agit des octets 1 à 4 :

octet 1octet 2octet 3octet 4
00100000001001101000000010110110


On affecte une valeur à la variable entière i :
	i=13;
	


La valeur des champs est modifiées pour enregistrer la valeur affectée :

octet 1octet 2octet 3octet 4
00000000000000000000000000001101

Pour exécuter i=0;, la machine va à l'adresse qu'elle connait pour la variable i (l'octet 1) et met la valeur 13 codée 1101 en binaire.
	int j=i;
	

Ici la machine crée un nouvel espace en mémoire vive pour stocker la variable j : imaginons que cela soit fait de l'octet 17 à l'octet 20 :

octet 17octet 18octet 19octet 20
00000000000000000000000000001101

Supposons maintenant :
	i=15;
	

Dans ce cas, la machine va à l'adresse qu'elle connait pour i et met la valeur 15 codée 1111 en binaire :

octet 1octet 2octet 3octet 4
00000000000000000000000000001111

la valeur de j n'est pas modifiée :

octet 17octet 18octet 19octet 20
00000000000000000000000000001101

Type Objet


	Voiture voit; //déclaration de variable objet
	

Supposons que le codage des variables objets se fait sur 4 octets et que la machine stocke la variable voit sur les octets 50 à 53. Le contenu qui est stocké pour la variable voit sera interprété comme un adresse sur la mémoire vive.

	new Voiture(); //instanciation
	

L'instanciation réserve de l'espace en mémoire pour stocker l'objet. La taille réservée en mémoire dépend de la taille de l'objet. Si l'objet a deux attributs qui sont des int, il faudrait 8 octets pour le stocker. Supposons que le stockage concerne les octects 100 à 107.

	Voit voit=new Voiture(); //Déclaration instanciation
	

Ici on crée deux espaces en mémoire : la machine crée l'espace pour la nouvelle instance stockée en mémoire vive : 100 à 107, puis elle crée un espace de 4 octets (50 à 53) dans laquelle elle enregistre le numéro de l'octet 100 : la variable "pointe" sur l'objet, son contenu est l'adresse de l'objet. Par suite, il devient possible de manipuler les attributs :

	voit.vitesse=5;
	


Ici, pour exécuter voit.vitesse=5, la machine sait que voit est à l'adresse 50, elle récupère le contenu de cette variable : l'addresse 100. La machine va à l'adresse 100 et affecte à l'espace qui correspond à l'entier vitesse la valeur 5. On peut alors créer une nouvelle variable objet :

	Voiture voit2=voit;
	

La variable voit2 est stockée aux octets 200 à 203, à cette adresse est affectée la valeur de la variable voit : soit l'adresse 100. De fait en faisant :

	voit.vitesse=7;
	

La machine sait que voit est à l'adresse 50, elle récupère le contenu de cette variable : l'adresse 100. La machine va alors à l'adresse 100 et affecte à l'espace qui correspond à l'entier vitesse la valeur 7. Dans ce cas, à quelle valeur est voit2.vitesse ?

	affiche(voit2.vitesse);
	

La machine sait que voit2 est à l'adresse 200, elle récupère le contenu de cette variable : l'adresse 100. La machine va alors à l'adresse 100 et récupère la valeur qui correspond à l'entier vitesse la valeur 7.


Attention : si on modifie i, on ne modifie pas j, si on modifie l'objet voit, on modifie l'objet voit2 : ces deux variables poitent en effet sur le même objet.

2 Hiérarchie d'objets

Tout langage objet définit un certain nombre de classes hiérarchisées. A tout moment, un certain nombre de classes sont "actives". Le progammeur peut vouloir en activer un certain nombre en fonction de ses besoins. Dès qu'un type d'objet est actif, on peut déclarer une variable de ce type. Le programmeur rajoute des types d'objets à la hiérarchie existante ou API (Application Programming Interface) : il peut créer des objets entièrement nouveaux ou des objets dérivés d'objets pré-existtant dans la hiérarchie du langage qu'il utilise en ajoutant des comportements. Par exemple, une collection d'images peut induire des comportements différents d'une collection d'objets en général : on peut vouloir comparer les images, les classer selon un certain ordre etc... Le bon niveau de granularité : il est possible de faire les opérations de la même manière qu'elles sont faites en programmation classique en programmation objet, sans définir un seul objet. Ce n'est bien sûr généralement pas la bonne démarche, de même que la démarche qui consisterait à créer trop d'objets pour une application simple serait une mauvaise démarche.

Pour chaque langage objet il existe une API officielle (celle donnée sur le site de Sun pour java par exemple) et des APIs spécifiques à certains domaines, développées et mises à disposition. Par exemple, une API de classes pour la 3D en java, des APIs de calcul scientifique etc...