POO par Jenny Benois-Pineau 25/03/2017
Introduction Pourquoi POO ? Crise du logiciel Robustesse, interchangeabilité des composantes, réutilisation du code, extensibilité, protection Langages : Java, Smalltalk, Eiffel, C++ Objectif de ce cours : appréhender les concepts objet à travers les langages C++ (essentiellement) et Java (exemples) 25/03/2017
POO vs PP/PI(I) Objet =<ensemble des données avec les opérations associées> PP : type abstrait=<données et traitements> PO : Objet =<données et traitements encapsulés> Exemple : modéliser une personne
POO vs PP/PI(II) Spécification Type abstrait Données - nom personne - la société Opérations -Se présenter= <afficher les informations> Objet … Le nom de la personne ne peut pas être modifié; Restreindre l’accès au champ « société »
POO vs PP/PI(III) La mise en œuvre C++ procédural Personne.hpp struct Personne { char Nom[25]; char Societe[32]; }; void SePresente(Personne P); Personne.cpp #include <iostream.h> #include <string.h> #include "personne.hpp" void SePresente(Personne P) { cout<<"Je m'apelle "<<P.Nom<<endl; cout<<"Je travaille à "<<P.Societe<<endl; } int main() Personne Ind; strcpy(Ind.Nom, "Toto"); strcpy(Ind.Societe, "ABC SARL"); SePresente(Ind); return 0;
POO vs PP/PI(IV) Les inconvénients Séparation des données des traitements Contrôles difficiles : … Personne Ind; SePresente(Ind); - le résultat??? Accès libre à toutes les composantes->possibilité de modifier malencontreusement
POO : encapsulation Objet P rassemble dans une même entité – encapsule- les données et les comportements Un objet contrôle ses comportements : P.SePresente() vs SePresente(P) On envoie un « message » à objet pour déclencher un traitement P.SePresente() L’objet vérifie que le message correspond à un des comportements qu’il encapsule (vérification au moment de la compilation) Comment déclarer un objet?
Classe : un moule pour les objets Personne + Nom + Societe + SePresente Classe P R Q Instancier
Classe C++ Fonction externe – utilise les objets Fonction-membre Personne.hpp Class Personne { public: char Nom[25]; char Societe[25]; void SePresente(); }; Personne.cpp #include ``Personne.hpp`` void Personne::SePresente(){ cout<<« Je m'appelle" <<Nom<<endl; cout<<"Je travaille à"<<Societe<<endl; } utilisePersonne.cpp #include <iostream> #include <string.h> #include "personne.hpp« using namespace std; int main() { Personne Ind; strcpy(Ind.Nom, "Toto"); strcpy(Ind.Societe, "ABC SARL"); Ind.SePresente(); return 0; Fonction externe – utilise les objets Fonction-membre
Discipline de programmation Une classe = (1) fichier .hpp (2) fichier .cpp Le pourquoi : (1)Séparation de la déclaration et d’implémentation (2)Compilation séparée 25/03/2017
Directives de pré-compilateur Lorsque on parle de compilation du programme on sous-entend traitement du code source par -pré-compilateur -compilateur proprement dit du fichier – résultant de la précompilation -fonctions du pré-compilateur : inclusion des fichiers, définitions des constantes et des macro-commandes, inclusion conditionnelle, pilotage des messages d’erreur. 25/03/2017
DIRECTIVE « include » Fichier MaClasse.cpp #include <iostream> #include “MaClasse.hpp ” #include “Util.h” using namespace std; // utilisation de l’espace de nommage int main(){ MaClasse C; … return 0; } 25/03/2017
Directive « define » Directive « define » est utilisée pour la définition des constantes, des macro-fonctions, Syntaxe : #define identificateur chaîne de substitution Ex : #define TailleMax 1000 classe Tableau{ int Tab[TailleMax]; int longueur_eff; }; 25/03/2017
Definition des macro-fonctions #define identificateur(paramètre,…) Exemple : #define ABS(x) x<0? x:-x …. x=-2; ABS(x); cette affectation sera substituée par x<0?x:-x Veiller à la correspondance du nombre et du type d’arguments: ABS(”ABC”) “ ABC ”<0? ”ABC ”:- ”ABC ” 25/03/2017
Inclusion conditionnelle(1) Compilation séparée : permet de corriger les erreurs de syntaxe, des erreurs de correspondance des déclarations aux implémentations, … pour chaque classe séparément. g++ -c MaClasse.cpp –compilation d’un fichier-source Résultat : MaClasse.o –fichier-objet 25/03/2017
Inclusion conditionnelle(2) Dans un fichier .hpp #ifndef MaClasse_H #define MaClasse_H class MaClasse{ ….. }; #endif 25/03/2017
Branchement conditionnel #ifdef identificateur Partie –alors #else Partie-sinon #endif Exemple : #ifdef VERBOSE cout<<“ Valeur a “ =<<a; 25/03/2017
Classe Java public static void main (String args[ ]){ Personne P; Personne.java import java.awt.*; Class Personne { public String Nom; public String Societe public void Se Presente(){ System.out.println ("Je m'appelle" +Nom); System.out.println ("Je travaille à" +Societe); } public static void main (String args[ ]){ Personne P; P=new Personne(); P.nom=Personne(); P. societe=``ABC``; P.SePresente(); //toute méthode fait partie d’une classe public void SePresente(){ Class Test{ public static void main(String args[ ]){ …..
Fonctions –membres C++(1) Personne.hpp Class Personne { public: char Nom[25]; char Societe[25]; void SePresente(); }; Personne.CPP void Personne::SePresente(){ cout<<« Je m'appelle" <<Nom<<endl; cout<<"Je travaille à"<<Societe<<endl; } inline void SePresente(){ cout<<Nom; cout<<Societe; Fonction inline : le code est recopié à la place de l’appel pour gagner du temps d’exécution
Fonctions –membres C++(2) Personne.hpp Class Personne { public: char Nom[25]; char Societe[25]; void SePresente(); }; Personne.CPP void Personne::SePresente(){ cout<<« Je m'apelle" <<Nom<<endl; cout<<"Je travaille à"<<Societe<<endl; } void SePresente() const{ cout<<Nom; cout<<Societe; char* surname () const {return Nom;}; Fonctions constantes – laissent l’objet inchangé
Fonctions constantes(1) On déclare les objets constants afin de ne pas pouvoir les changer (héritage du langage C) class point { public : double x; double y; void affiche(); }; const point c; c.affiche(); //erreur de compilation 25/03/2017
Fonctions constantes(2) ….. public : Double x; Double y; void affiche(); //les deux fonctions sont identiques void affiche () const; // mais! }; …. int main(){ const point c; c.affiche(); //compilation normale, c’est la méthode « const » qui est invoquée … } Java : la notion de fonction membre constante n’existe pas 25/03/2017
Protection des membres Personne - Nom - Societe + SePresente + Public - Private O Protected 25/03/2017
Protection des données Personne.hpp Class Personne { private : char Nom[25]; char Societe[25]; public : void SePresente(); }; Personne.CPP void Personne::SePresente(){ cout<<« Je m'appelle" <<Nom<<endl; cout<<"Je travaille à"<<Societe<<endl; } utilisePersonne.cpp #include <iostream.h> #include <string.h> #include "personne.hpp" int main() { Personne Ind; strcpy(Ind.Nom, "Toto"); Erreur de compilation strcpy(Ind.Societe, "ABC SARL"); Ind.SePresente(); return 0;
Accessibilité Classe Nom_Cls private public Fonctions usuelles 25/03/2017
Masquage de l’information File.hpp Class File{ private : xxxxxxxxxxx public : void enfiler(int valeur); void defiler(); int valeur_file const(); …….. }; Masquage de l’implémentation La modification de la partie privée n’affecte pas les programmes applicatifs – efficacité du processus de développement. 25/03/2017