Résumé Principe Programmation Orienté Objet PDF

Title Résumé Principe Programmation Orienté Objet
Course Programmation Orienté Objet
Institution Haute École Louvain en Hainaut
Pages 13
File Size 400.3 KB
File Type PDF
Total Downloads 70
Total Views 148

Summary

Résumé Principe de Programmation Orienté Objet, Matière jusque Janvier.

...


Description

PPOO : Matie re de l’examen Chapitre 1 : Concepts de bases Langage procédural Langage basé sur des appels de procédures. Une procédure contient une série d'étapes à réaliser et n'importe quelle procédure peut être appelée à n'importe quelle étape de l'exécution du programme. Cette approche permet de réutiliser le même code à différents emplacements du programme.

Langage Orienté Objet La programmation orientée objet répartit l’effort de résolution des problèmes sur un ensemble d’objets communiquant entre eux. Un objet représente un concept ou une entité physique. Chaque objet est composé de 2 parties : une partie statique (les attributs) qui décrit l’objet et une partie dynamique qui détermine les comportements de celui-ci. Dans la partie dynamique, on retrouve du langage procédural.

Langage compilé Langage dont le code source (la suite d’instructions respectant la syntaxe d’un langage choisi) est converti en fichier binaire compréhensible directement par la machine. On parle de fichier exécutable. L’inconvénient est que le fichier doit être compilé pour chaque OS.

Langage interprété Langage dont le code source est convertit en langage machine sans être compilé. La plupart du temps, ces langages sont multiplateformes mais nécessitent l’installation d’un interpréteur pour assurer la traduction du code source.

Langage intermédiaire Certains langages utilisent les deux mécanismes précédents car ils passent d’abord par une précompilation dans un langage intermédiaire (appelé pseudo-code), c’est ce langage qui sera interprété.

Objet Entité définie par un ensemble d’attributs prenant une certaine valeur.

Attribut Il permet de décrire une entité, caractéristique de celle-ci.

Référent Chaque objet doit avoir un nom unique car il est son seul et unique identifiant. L'accès à l'objet se fait via le nom. Le référent est une variable informatique stockée dans un espace dédié uniquement aux noms symboliques. On assigne à cette variable l’adresse physique de l’objet (sur 32 bits mais est en train de passer à 64 bits) ce qui donne 232 emplacements différents disponibles (232 = 4.294.967.296 et 264 = 18.446.744.073.709.551.616). En Java, si on imprime le contenu d'un référent, le type de l'objet référence ainsi que son adresse en mémoire sont affichés (ex : [I@3e25a5 --> tableau d'entiers à l'adresse 3e25a5 (hexadécimal)).

Adressage indirect L’adresse d’un objet se trouve dans plusieurs référents ; ce qui va nécessiter l’utilisation d’un espace mémoire supplémentaire

Référents :

Mémoire des objets

UneVoiture

Objet

Couleur= « bleue »

4b2114

4b2114

Prix=20000.00

5c1441 |--------|

5c1441

4b2114

LaMemeVoiture 5c1441 |--------|

Par contre, il n’est pas possible de stocker les adresses de plusieurs objets dans un seul référent. On dit d’un objet qu’il est mort lorsque plus aucun référent ne possède son adresse.

Etat d’un objet L’état d’un objet est l’ensemble des valeurs des attributs de cet objet à un moment donné. Cycle de vie d’un objet : • • •

Naissance (création) Succession de changement d’états Mort (suppression)

Un objet change d’état suite à des mécanismes propres (exemple : opération appelée après un certain temps) ou suite à une interaction avec un autre objet (exemple : perte de valeur d’une voiture suite à un accident).

Chapitre 2 : Classes Classe (définition et représentation) Une Classe est un modèle à respecter strictement pour les objets. Un objet reste toujours lié à sa classe. Autrement dit, il n’est pas possible de changer la classe d’un objet après sa création. Représentation d’une classe en UML : Nom de la Classe Attributs

Méthode

Employe -nom : String -prénom : String -salaire : double +changerSalaire(newsal : double) : void +calculerSalaire() : double

Pour les attributs, on trouve 3 parties : 1) Le modificateur d’accès : Il y a 3 valeurs possibles : a) Private ( - ) : visible uniquement dans la classe où l’attribut/méthode est déclaré. b) Protected ( # ) : visible uniquement par les sous classes de la classe où l’attribut/méthode est déclaré. En java, accès également aux classes du même package. c) Public ( + ) : visible pour toutes les classes. 2) Le nom de l’attribut 3) Le type de l’attribut Pour les méthodes, on trouve 4 parties : 1) Le modificateur d’accès (voir Attributs) 2) Le nom de la méthode 3) Les arguments de la méthode sous la forme : (nomArg : type) mais on peut ne mettre que le type

4) Le type de retour de la méthode

Retour d’une méthode Si une méthode doit pouvoir retourner un résultat, il faut préciser qu’il y a un retour à cette méthode (par exemple : la méthode nextInt() de la classe Scanner) Pour préciser qu’une méthode effectue un retour, il faut remplir deux conditions : 1) Trouver une instruction telle que « return … » ; dans le corps de la méthode(les « … » étant remplacé par une valeur, une variable ou une expression). 2) Le type de retour doit précéder le nom de la méthode et être d’un type compatible avec la valeur renvoyée. S’il n’y a pas de retour, void précède le nom de la méthode. En procédural, on distingue fonction ( avec retour) et procédure ( sans retour). Toute méthode peut recevoir un ensemble d’arguments entre les (). La méthode utilise ses arguments pour moduler son comportement. Exemple En java : public class Employe { // définition de la classe private String nom ; private String prenom ; // Attributs private double salaire; public void changerSalaire(double nouveauSalaire){ //En-tête de la méthode(paramètre formel) salaire=nouveauSalaire ; // corps de la méthode } public double calculerSalaire(double taux){ return salaire*taux ; } } public class Start{ public static void main(String[]args){ Employe empl=new Employe(); empl.changerSalaire(2000); double salaireEmpl=empl.calculerSalaire(0.5); } }

Encapsulation Pour conserver l’intégrité des valeurs des attributs, il est nécessaire de ne pas donner accès aux attributs en dehors de la classe (mot-clef private). Pour récupérer ou modifier la valeur d’un attribut, il faut prévoir des méthodes publiques. On retrouve parmi ces méthodes : • • •

Accesseur en lecture (getter ) : méthode qui permet de récupérer la valeur d’un attribut. Accesseur en écriture (setter) : méthode qui permet de modifier la valeur d’un attribut.

Intérêts • •

La classe peut contrôler la valeur prise par les attributs. Choisir les accès donnés aux attributs.

Signature de méthode (définition, utilité, limitation) La signature de méthode est composée du nom de la méthode et de la liste des types des arguments. La signature est associée de manière unique au corps de la méthode. Elle permet de retrouver la méthode dans la mémoire des méthodes. Deux méthodes ne peuvent pas partager la même signature.

Surcharge de méthode La surcharge de méthode consiste à définir une méthode qui porte le même nom qu’une autre méthode mais dont la signature diffère par le nombre et/ou le type des arguments. /!\ le type de retour n’intervient ni dans la signature ni dans la surcharge de méthode. Exemple de surcharge : public class Employe { public void changeSalaire() { /* bloc d’instructions */ } public void changeSalaire(double nouvSalaire) { /* bloc d’instructions */ } public int changeSalaire(double nouvSalaire, double taux) { /* bloc d’instructions */ } public void changeSalaire(double a, double b) NON VALIDE, SIGNATURE EXISTANTE { /* bloc d’instructions */ } }

Constructeur Le constructeur est une méthode particulière portant le même nom que la classe (en java) et définie sans aucun retour. Le constructeur a pour but d’initialiser les variables d’instances d’un objet. Il n’est appelé qu’une fois, lors de la création d’un objet. Comme toute méthode, il peut être surchargé.

Si aucun constructeur n’est défini dans la classe, alors un constructeur par défaut sans argument est accessible. Dès qu’un constructeur est défini explicitement, ce mécanisme de constructeur implicite n’est plus disponible. Il est appelé à l’aide du mot réservé « new ».

Comparaison des objets (distinction entre == et equals)

En comparant des référents avec l’opérateur ==, on compare en réalité leur adresse et non leur contenu. Pour pouvoir comparer des objets d’une même classe sur leur contenu, il faut prévoir dans cette classe la méthode equals. Dans cette méthode, les critères de comparaisons de deux objets de cette classe seront définis. /!\ Préférer créer la méthode equals dans la classe que de faire des comparaisons sur les attributs car cela permet de modifier plus rapidement ce qu’il faudrait éventuellement changer (et car c’est moins lourd à écrire).

Variable de classe Exemple : Imaginons que tous les employés d’une entreprise gagnent le même salaire. Cet attribut va devenir alors un attribut lié à la classe plutôt qu’à un objet. Une variable d’instance est un attribut dont la valeur est propre à chaque objet. Une variable de classe est un attribut dont la valeur est partagée par tous les objets de la classe. Dans une représentation UML, une variable de classe est soulignée. En java, on ajoute le mot-clef « static » devant le type de la variable de classe. /!\ Ne pas initialiser les variables de classes dans les constructeurs. Une variable de classe doit être initialisée au moment de sa déclaration (sinon initialisation implicite). Une variable de classe existe même si aucun objet de cette classe n’a été créé.

Méthode de classe Si on utilise une méthode d’instance pour modifier/récupérer une variable de classe, il faut alors obligatoirement créer un objet. Pour remédier à cela, on va créer une méthode de classe pour gérer les variables de classe. Intérêts des méthodes de classe : •

Les méthodes d’instances s’exécutent sur des objets et manipulent des variables d’instances. Autrement dit, un objet doit être créé pour pouvoir les utiliser.





Dans le cas des variables de classe, on doit pouvoir les manipuler sans créer d’objet. On va donc écrire des méthodes de classe qui ne manipulent que des variables de classe et faire appel qu’à des méthodes de classe. Elles donnent la possibilité à la classe de rendre un service indépendamment de variables d’instances (exemple : la classe math) car est lié à des classes en Java.

Chapitre 3 : Héritage et polymorphisme H iérarchie (intérêt + comment la construire) Lorsque l’on réalise un programme, on peut se rendre compte que certaines classes partagent des caractéristiques communes (attributs ou méthodes). Réécrire plusieurs fois ces caractéristiques communes est souvent contraignant et peut être source d’erreurs. Il est aussi toujours préférable d’éviter la redondance dans le code car cela facilite la maintenance (qui ne se fera donc qu’à un seul endroit plutôt qu’à plusieurs). La solution est de construire une hiérarchie de classe. L’objectif est de repérer tout ce qui est commun entre les classes qui constitueront la hiérarchie. Il y aura donc au-dessus des classes générales et dans le bas de la hiérarchie des classes spécialisées. Les caractéristiques communes sont rassemblées dans une super-classe et les spécificités se retrouveront dans les sous-classes. Il ne sera donc plus nécessaire de réécrire le code commun et la maintenance ne concernera plus qu'une seule classe (celle contenant la méthode à modifier). On ne trouve donc dans la sous-classe que des caractéristiques additionnelles ou des précisions par rapport à sa super-classe. Les nouveaux attributs et méthodes sont les seuls qui doivent être précisés dans la sous-classe. L'héritage est représenté en UML par un trait terminé par un triangle. Le triangle touche la superclasse. En Java, l'héritage se représente dans la sous-classe à la suite du nom de la classe avec le mot-clé extends suivi du nom de la super-classe.

Héritage (propriétés) 1) Une sous-classe hérite des attributs et des méthodes de sa super-classe. Elle hérite également des associations de sa super-classe. Les variables de classe de la super-classe sont partagées entre la super-classe et la sous-classe (il n'y a qu'une valeur pour la hiérarchie). (En ce qui concerne l'héritage des attributs, il faut noter que les objets de la sous-classe possède bien ses attributs dans leur structure mais que leur accès ne peut pas se faire directement dans la sous-classe à cause de l'encapsulation (les attributs privés ne sont accessibles que dans la classe dans laquelle ils sont définis et dans aucune autre même pas les sous-classes). Les accès aux attributs hérités de la super-classe se font donc via l'utilisation des méthodes prévues à cet effet. Tout objet, instance de la sous-classe, possède alors deux ensembles d’attributs : ceux qui lui sont propres (avec un accès direct) et ceux hérités de sa super-classe (avec un accès via les méthodes publiques).).

2) Un objet d’une sous-classe peut donc toujours au moins faire ce qu’un objet de la superclasse peut faire mais l’inverse n’est pas vrai. Tout ce qui est défini dans la super-classe peut être utilisé dans la sous-classe. 3) Il est fréquent que la sous-classe ajoute des attributs et des méthodes par rapport à sa superclasse. On ne trouve dans la sous-classe que les ajouts par rapport à la super-classe. Le constructeur a alors comme utilité d'initialiser non seulement les attributs définis dans une classe mais également ceux des super-classes. En effet, la première instruction d'un constructeur est TOUJOURS un appel vers un constructeur de la super-classe. Si cet appel est implicite, il s'agit alors d'un appel vers le constructeur sans argument. Pour un appel vers tout autre constructeur, il faudra un appel explicite à l'aide de « super (liste des arguments) ».

Recherche d'une méthode dans la hiérarchie Lors de l’appel d’une méthode sur un objet (quelle que soit sa classe), la recherche de méthode se fait d’abord dans la classe correspondant au type réel de l’objet, si elle ne s’y trouve pas, elle sera recherchée dans la super-classe en remontant la hiérarchie. Toutes les méthodes dans sa hiérarchie peuvent s’appliquer sur un objet.

Redéfinition de méthode (définition + utilité) On parle de redéfinition de méthode lorsqu’une méthode dans une sous-classe possède la même signature et le même type de retour qu’une méthode de la super-classe dont elle hérite. La méthode redéfinie cache la méthode de la super-classe. La sous-classe donne un nouveau comportement à la méthode redéfinie (soit en donnant une définition tout à fait nouvelle soit en utilisant ce qui se fait dans la super-classe). Lors de la redéfinition d’une méthode, le modificateur d’accès (private, public, protected) peut devenir moins sévère (de private à public) mais jamais plus sévère (de public à private). Pour rappel, une sous-classe doit pouvoir au moins faire ce que fait sa super-classe. Pour faire appel à la méthode définie dans la super-classe, on utilise le mot-clé super. Sans ce mot-clé super, on fait appel à la méthode de la classe courante.

Principe de substitution (définition + expliquer pourquoi cela fonctionne) Lorsqu’on crée un référent d’une super-classe, on peut, sans que cela pose de problème, y placer un objet, instance d’une sous-classe. Raison : tout message compris par un objet d’une super-classe le sera obligatoirement par tous les objets issus des sous-classes.

Forçage de type (intérêt + instanceof) Si l’on utilise le principe de substitution, il peut être parfois tout de même utile de se servir de méthode présente dans la sous-classe. Comme l’objet sera pour le compilateur du type de la superclasse, une méthode de la sous-classe ne peut être appelée dessus sans un forçage de type préalable. Malgré le forçage de type, une erreur d’exécution peut se produire si l’objet sur lequel on applique le forçage de type n’est pas du type réel de la sous-classe. Il est donc préférable d’utiliser le instanceof pour vérifier si l’objet est bien du type désiré.

Polymorphisme Le polymorphisme est une conséquence directe de l’héritage et de la redéfinition de méthode. Grâce au polymorphisme, si un objet d’une sous-classe est stocké dans un référent du type de la super-classe, une méthode qui serait redéfinie dans la sous-classe sera utilisée comme elle a été redéfinie dans la sous-classe. EXEMPLE : public class Produit { private String libelle; private double prix; public Produit(String libelle, double prix) { this.libelle = libelle; this.prix = prix; } public String toString() { return "Libellé : "+libelle+"\tPrix : "+prix+"€"; } public double calculerPrix() { return getPrix(); } public double getPrix() { return prix; } } public class ProduitAlimentaire extends Produit { private String dateLimiteConsommation; public ProduitAlimentaire(String libelle, double prix, String dateLimiteConsommation) { super(libelle, prix); this.dateLimiteConsommation = dateLimiteConsommation; } public String toString() { return "Produit alimentaire\t"+super.toString()+"\tDLC : " +dateLimiteConsommation; } public double calculerPrix() { return super.calculerPrix() * 0.06; } } public class ProduitNonAlimentaire extends Produit { private int delaiLivraison; public ProduitNonAlimentaire(String libelle, double prix, int delaiLivraison) { super(libelle, prix); this.delaiLivraison = delaiLivraison; } public String toString() { return "Produit non alimentaire\t"+super.toString()+"\tDélai de livraison : "+delaiLivraison; } public double calculerPrix() { return super.calculerPrix() * 0.21; } } public class StartPolymorphisme { public static void main(String[] args) { Produit[] tabProduit = new Produit[2]; tabProduit[0] = new ProduitAlimentaire("Chocos",4,"30/05/2012"); tabProduit[1] = new ProduitNonAlimentaire("BD Intégrale Murena 1" ,39.0,7); for (int i=0;i résultat de l'appel de la méthode calculerPrix de ProduitNonAlimentaire

Méthodes et classes abstraites Une classe abstraite est une classe que l’on ne peut pas instancier. Elles n’ont pour but que la mise en commun de classe. Une méthode abstraite est une méthode sans corps dont le but est de forcer la définition de ses méthodes dans les sous-classes. Si une sous-classe ne redéfinit pas une méthode abstraite de la superclasse, cette classe doit être elle aussi abstraites.

Interface Une interface est une structure qui contient uniquement des en-têtes de méthodes. Les méthodes qu'elle contient sont donc toutes abstraites. Une classe qui implémente une interface doit donner une définition à toutes les méthodes de l'interface. Dans le cas contraire, la classe devra être abstraite. Une interface regroupe donc un ensemble de méthodes qui pourront être appelées par les objets utilisant les objets venant d'une classe implémentant cette interface. Si une classe ne peut hériter que d'une seule super-classe (en Java), elle peut implémenter plusieurs interfaces. Les attributs ne peuvent pas être définis dans une interface, les seuls variables acceptées sont des constantes de classe. Une constante est une variable dont la valeur ne peut plus être modifiée dès qu'elle a été initialisée.

En UML, l'implémentation d'une interface se représente par un trait pointillé terminé par un triangle. Le triangle touche l'interface. Une interface est représentée avec le mot « interface » suivi du nom de l'interface dans la case réservée au nom de la classe/interface. En Java, le mot-clé implements suivi du nom de l'interface se trouvent à la suite du nom de la classe implémentant l'interface. Dans une interface, on trouve le mot-clé interface au lieu du motclé class. Comme les attributs d'une classe doivent être privés (encapsulation), seules les méthodes d'une classe peuvent être publiques. La seule chose qu'un programmeur doit donc connaître d'une classe est la liste des en-têtes des méthodes qui peuvent être appelées. Cette liste peut donc être reprise dans l'interface ce qui facilite le travail en équipe.

Chapitre 4 : Communication entre les objets Associati...


Similar Free PDFs