1.33k likes | 1.93k Views
Programmation Objet en Java. Chapitre II. Au sommaire de ce chapitre…. 1. Bases de la POO en Java ------- --- 3 Rappels notions de classe et d’objets, modificateurs d’accès, constructeurs, clonage… 2. Rappels sur l’héritage ------------------ 45
E N D
Programmation Objet en Java Chapitre II
Au sommaire de ce chapitre… 1. Bases de la POO en Java ------- --- 3 Rappels notions de classe et d’objets, modificateurs d’accès, constructeurs, clonage… 2. Rappels sur l’héritage ------------------ 45 3. L’héritage en Java ----------------------- 54 4. Interfaces ---------------------------------- 71 5. Classes internes ------------------------- 79 VDe
Généralités • Java est un langage complètement orienté objet • un programme Java n'est constitué que de classes • il n'existe pas de fonctions ou de procédures isolées, définies en dehors d'une classe • Parfois on invente artificiellement une classe : Class EstPair { public static boolean p(int n) { return (n%2)==0; } Appel : EstPair.p(144); • il n'y a que des méthodes : • d'instance (agissent sur les objets de la classe) • de classe (agissent sur la classe et non les objets) VDe
Notion de classe : rappels • La notion de classe est un enrichissement de la notion usuelle de TYPE • TYPE : utilisé en programmation • CLASSE : déjà vue en algo avec les Types Abstraits de Données • Regroupe un ensemble de données (= champs représentant l’état de l’objet évoluant au cours de l’exécution • ex. la position d’une fenêtre sur un écran, si elle est active ou pas…) • et de comportements • Ex. s’afficher, s’agrandir, se détruire… VDe
Notion d’objet : rappels • Un objet est une instance de classe • La notion d’objet est plus riche que la simple valeur d’un type • VALEUR : int n=12; // 12 est une valeur • pas un objet identifiable (référençable) • OBJET : Fenêtre frame1; // frame possède une identité propre • on peut le manipuler à part entière VDe
La POO, c’est la classe … • Si la POO se limitait à la notion de classes et d’objets • Simple méthodologie de structuration des données • Pas besoin d’un langage spécifique • La notion d’héritage est plus profonde • Elle doit être offerte par le langage • Elle permet de définir une hiérarchie de types, des plus généraux aux plus spécialisés • Elle entraîne d’autres notions, comme les méthodes virtuelles Logiciels extensibles, réutilisation VDe
Le type class • Permet de définir une classe au sens de la POO modifAcces class nomClasse […] { modifAcces type attribut1; modifAcces type attribut2; ... modifAcces typeRetourne methode1(type param){} modifAcces typeRetourne methode2(type param){} ...} • Le ; à la fin de la définition est facultatif en Java • Toutes les classes dérivent de la même méta-classe appelée Object • Toutes les instances seront créées dynamiquement VDe
Client String nomClient int codePostalClient float soldeClient float getSolde (String) EXEMPLE public class Client { // variables d'instance String nomClient; String codePostalClient; float soldeClient; … // méthodes d'instance float getSolde (String cli) { … } … } Déclaration Variable d'instance Méthode d'instance VDe
Les modificateurs d'accès • Les modificateurs d'accès (ou indicateur d’accès) servent à fixer les règles de visibilité : • de la classe elle-même • des membres de la classe (attributs et méthodes) • Trois modificateurs de classe : précisé à la définition de la classeniveauAcces nomClasse {...} Valeurs : public / abstract /final • Trois modificateurs pour les membres de classe: public private protected VDe
Modificateurs d'accès …de classe • Les valeurs possibles sont : • public : classe publique, accessible par toutes les autres classes, même en dehors du package la contenant (si package importé) • abstract : la classe est abstraite (pas d’instance directe) les méthodes (abstraites) qu’elle contient seront implémentées dans les sous-classes : les classes dérivées C’est le principe de délégation • final : classe finale de la branche d’héritage, elle ne peut plus être dérivée • par défaut, si on ne précise pas de niveau d’accès une classe n'est visible que pour les classes du package VDe
Modificateurs d'accès… des membres • Les modificateurs d'accès des membres : sont répétés pour chaque attribut et chaque méthode de la classe • Visibilité d'un membre de la classe • public: accessible par toutes les classes de tous les packages utilisés (idem que pour les classes) • protected: accessibilité restreinte à la classe et à ses classes dérivées (du même package ou non) • private: accessibilité réduite à la classe • par défaut, accessibilité réduite au package VDe
Portée des modificateurs d'accès • Les protections sont définies : • au niveau de la classe • et non au niveau de l'objet • Par conséquent : • toutes les méthodes (privées et publiques) d'un objet ont accès bien sûr aux membres de cet objet • MAIS aussi aux membres -même privés- d'un autre objet de la même classe • Si l’accès à la classe le permet VDe
Les objets (1/3) • L'instance d'une classe est un objet • un objet est créé par un constructeur • il est détruit par le destructeur • son état est caractérisé par les valeurs de ses attributs • son comportement est défini par ses méthodes • En Java un objet ne peut être alloué que de façon dynamique • grâce à l'opérateur new VDe
Les objets (2/3) • Création en 2 temps : • Déclaration –(on dit aussi définition) d’un identificateur qui va être une référence (sur l’objet) • Assignation – affectation d’un espace mémoire pour les attributs et méthodes de l’objet • (1) Définition d'un objet • pour référencer un objet, il faut définir une variablenomClasse nomObjet; • attention la variable n'est qu'une référence sur un objet de type nomClasse l'objet n'est pas créé • (2) Assignation de l'objet: appel au constructeur nomObjet = new nomClasse(); VDe
Les objets (3/3) • Définition et création d'un objet en même temps : nomClasse nomObjet = new nomClasse(); • Référence nullenomObjet = null; VDe
Film film1; La variable d'objet est initialisée à null film1 = new Film(); new la variable d'objet pointe sur un objet Processus de création d’un objet OU Film film1 = new Film(); La variable d'objet est créée et pointe sur un objet VDe
Destruction d’un objet • Les instances de classe sont détruites automatiquement par le gestionnaire de mémoire • si elles ne sont plus référencées • Un objet peut être marqué pour le gestionnaire de mémoire en supprimant toutes les références à cet objet • en les mettant ànull • On ne sait pas quand exactement le gestionnaire agit • On a la possibilité de personnaliser la destruction : définir une action à faire lors de l’élimination de l’objet • On utilise la méthode finalize() VDe
film1 titre: null categorie: null film2 Affectation de Références Affectation d'une référence à une autre deux références au même objet Film film1 = new Film(); Film film2 = film1; VDe
Que fait new exactement ? • Lors de la création d'une instance avec new :nomObjet = new NomClasse(); • L’opérateur new : • alloue de la mémoire pour le nouvel objet. • appelle un constructeur pour initialiser les valeurs des attributs de l'objet. • renvoie (dans nomObjet) une référence sur le nouvel objet créé qui pointe sur l'emplacement de l'objet en mémoire. VDe
Les attributs (1/2) • Un attribut est soit une variable d'instance, soit une variable de classe • Variable d'instance • Variables utilisées par les objets d'une classe. • Décrit l'état de l'objet : état propre à chaque instance de la classe • Sa portée par défaut = la classe (il est accessible par toutes les méthodes de la classe) • Accès : • si définie en private: par les méthodes de la classe uniquement nomAttribut • si définie en public : par l'opérateur "." nomObjet.nomAttribut (hors la classe) VDe
Variables d'instance et encapsulation • L'encapsulation est un concept clé en programmation orienté objets. • en dehors de la classe, on ignore les détails d’implémentation • Utilisation des objets par l'intermédiaire d'interfaces • Permet d'utiliser des objets sans savoir comment ceux-ci fonctionnent (par exemple un magnétoscope, un guichet automatique de banque, etc.). • Respect de l'encapsulation : • Les variables d'instance doivent être déclarées privées • Seules les méthodes d'une classe (public)peuvent avoir accès aux variables d'instance de cette classe. VDe
Les attributs (2/2) • Variable de classe (static) • Caractérise la classe et non un objet • Attribut commun à toutes les instances • Permet de factoriser une propriété • déclaration[visibilité] static type nom [= valeur]; • initialisée à la déclaration ou par une méthode de classe • si l'accès depuis l'extérieur de la classe est autorisé nomClasse.nomAttributStatique • si la variable de classe est une constante elle doit être déclarée static final type nom = valeur; VDe
Les méthodes de classe • On distingue les méthodes : • de classe • d'instance • Méthode de classe(static) • Existe même sans qu’aucune instance ait été créée • Permet de manipuler les variables de classe • N'opère pas sur une instance particulière • on ne peut pas utiliser la référence this sur l'objet courant • Syntaxe :[visibilité] static type_retour nomMéthode(arguments) { corps } VDe
Exemple public class ex7 {public static void main(String[] args) { int i,j,k; System.out.println("Bonjour"); j=calcul(8,9); System.out.println(j);}static int calcul(int x, int y) { int a; a=x+y; a=a*2; return a;} } Méthodes de classe VDe
Les méthodes d'instance (1/2) • Servent à décrire le comportement d'un objet • Sont propres à chaque instance • Règle de visibilité • publique pour les services offerts par la classe • privées pour cacher les détails d'implémentation • Définition[visibilité] typeRetour nomMéthode(arguments) { corps } • Type retourné : void, type primitif, classe ou interface VDe
Les méthodes d'instance (2/2) • Surcharge possible d'une même méthode et uniquement par le type des arguments • Passage d'arguments par valeur uniquement • une méthode ne peut donc pas modifier un argument directement • sauf pour un tableau ou un objet • car ce sont des références • MAIS une méthode peut modifier l'état d'un objet passé en argument • à travers les méthodes publiques de cet objet VDe
Cas des constructeurs • Toute création d'objet fait appel à un des constructeurs de la classe par new • Propriétés des constructeurs • on peut définir plusieurs constructeurs pour une même classe grâce à la surcharge • un constructeur, défini sans argument, est appelé constructeur par défaut • si aucun constructeur n'est défini, Java crée un constructeur public par défaut sans paramètre qui ne fait rien • (à part allouer de la mémoire !) VDe
Propriétés des constructeur (suite) • si un ou plusieurs constructeurs sont définis • il n'y a pas de constructeur par défaut • d'où l'intérêt de toujours définir un constructeur par défaut • un constructeur peut invoquer un autre constructeur de la même classe par this • Ex. ci-après • l'identificateur d'un constructeur est toujours le nom de la classe • un constructeur ne retourne rien • Il est habituellement déclaré public suite VDe
public class Film { public class Film { private private String titre; String titre; appel d'un autre constructeur private private String String categorie categorie ; ; public Film() { public Film() { this this ("categorie0"); ("C"); } } public Film(String public Film(String nvlCategorie nvlCategorie ) { ) { categorie categorie = = nvlCategorie nvlCategorie ; ; } } } } Ex.: plusieurs constructeurs L'appel à this() doit être la première instruction du constructeur; Les arguments de this() doivent correspondre à ceux du constructeur appelé. retour VDe
clonage = copie en profondeur Clonage et références • Une référence permet d'atteindre un objetnomClasse ref1 = new nomClasse(); • L'affectation d'une référence par une autre référence ne copie pas l'objet • mais permet de désigner le même objetnomClasse ref2 = ref1; • Une recopie d'un objet sur un autre de la même classe s’appelle un clonage • duplique correctement les variables d'instance VDe
Clonage et références • Pour cloner correctement il faut implémenter la méthode protégée clone de la métaclasse Object qui effectue une copie binaire membre à membre • (ne fait pas appel à un constructeur) • Donc plusieurs situations • soit la méthode convient car les membres sont des types primitifs et la copie est correcte Rectangle r3 = r1.clone(); • soit il faut surcharger la méthode clone car il y a des attributs qui sont des références VDe
Opérateur = Clonage correct référence2 = référence1.clone(); référence2 = référence1; valeur 2 valeur 1 valeur 3 valeur 1 valeur 2 valeur 1 valeur 2 valeur 3 valeur 3 référence 2 référence 1 référence 1 référence 2 Champs de types primitifs Clonage Objet à copier Pas de copie ! VDe
Clonage correct référence référence référence référence valeur valeur valeur valeur valeur valeur valeur valeur valeur valeur valeur valeur valeur valeur référence 1 référence 1 référence 2 référence 2 Clonage Erreur de clonage référence2 = référence1.clone(); Création d’un nouvel objet pour la copie Champs de type référence VDe
Egalité d'objets et références • L'égalité entre deux objets de la même classe consiste à tester si leurs attributs respectifs ont les mêmes valeurs • Or l'opérateur == • ne fonctionne que sur les types de base • car pour les autres types il compare les références et non les objets désignés • Il faut utiliser alors pour cela la méthode d'égalité equals de la classe Object et la surcharger en fonction des besoins de la classe : r3.equals(r1) VDe
Avec l'opérateur = = Avec une méthode Equals valeur 1 valeur 2 valeur 2 valeur 2 valeur 1 valeur 2 valeur 1 valeur 1 ? ? référence 1 référence 1 référence 2 référence 2 Egalité VDe
Surcharge de equals() • Exemple : tester l’égalité de deux fractions 1/2=2/4=3/6, ces fractions étant des objets (champs numérateur et dénominateur) et non des réels… Sachant que les multiplications croisées donnent le même résultat, surcharge de equals(): public boolean equals(Fraction f){ return (this.numerateur * f.denominateur == this.denominateur * f.numerateur); } VDe
Egalité de surface vs. en profondeur (1/2) • Cas où les variables d'instance des objets à comparer ne contiennent pas de valeurs primitives. • Exemple : une liste de rectangles : Class ListeRect { private Rectangle[] lesRectangles; private int nbRectangles; … } • Égalité de surface (clonage de surface) : on peut décider que ListeRect a et b sont égales si elles font références aux mêmes rectangles : a.lesRectangles[0] == b.lesRectangles[0] a.lesRectangles[1] == b.lesRectangles[1] etc. VDe
Egalité de surface vs. en profondeur (2/2) • Égalité en profondeur : deux ListeRect sont égales si elles contiennent des rectangles égauxdeux à deux… le test equals() se propage en profondeur dans les composantes des objets à tester : a.lesRectangles[0].equals(b.lesRectangles[0]) a.lesRectangles[1].equals(b.lesRectangles[1]) Etc. VDe
super fait référence au parent de l'objet courant. Exemple : points, segments (1/4) • Extrait de la classe Point Classe d’interface : Objet clonable Attributs privés Accesseurs VDe
class Segment implements Cloneable { private Point debut; private Point fin; // définition des constructeurs Segment(int xa, int ya, int xb, int yb) { debut = new Point(xa,ya); fin = new Point(xb,yb); } Segment() { debut = ne w Point(); fin = new Point(); } // méthode d'affichage d'un segment public void affiche() { System.out.println(" \ ndebut :" +debut. g et X () +";"+debut. g et Y ()); System.out.println(" \ nfin : " +fin. g et X () +";"+fin. g et Y ()); } Exemple (2/4) • Extrait de la classe Segment Attributs privés VDe
// clone à redéfinir obligatoirement car il y a des références public Object clone() throws CloneNotSupportedException { Segment s = (Segment) super.clone(); s.debut = (Point)debut.clone(); s.fin = (Point)fin.clone(); return s; } // surcharge de la méthode equals() d'Object public boolean equals(Segment s) { if (debut.getX()==s.debut.getX() && debut.getY()==s.debut.getY () && fin.getX()==s.fin.getX() && fin.getY()==s.fin.getY()) return true; return false; } // methode de translation d'un segment public void translation(int tx, int ty) { debut.translation(tx,ty); fin.translation(tx,ty); } } // fin de la classe Segment Exemple (3/4) : clonage de segments • Extrait de la classe Segment VDe
Exemple (4/4) • Test du clonage et de l'égalité de Segment VDe
Java versus C++ • Quelques différences notables: • pas de variables globales • l'amitié et la surcharge d'opérateurs n'existent pas • toutes les méthodes sont définies à l'intérieur d’une classe • pas de valeur par défaut aux paramètres et le seul mécanisme est le passage par valeur • pas de méthodes constantes VDe
Définition • Mécanisme qui permet de définir une classe dite classe dérivée, à partir d’une classe plus générale dite classe de base • la classe dérivée hérite des caractéristiques de la classe de base • la classe dérivée peut ajouter des données membres données et/ou des fonctions membres • la classe dérivée peut adapter des fonctions membres de la classe de base sans que cela les modifie au niveau de la classe de base VDe
Principe de substitution • Principe de Liskow: un objet d’une classe dérivée doit pouvoir être utilisé à tout endroit où on attend un objet de la classe ancêtre • L’inverse n’est pas vrai ! • Les liens d’héritage • forment un arbre dans le cas de l’héritage simple • forment un graphe acyclique dans le cas de l’héritage multiple VDe
une classe fille = sa classe mère + d'autres propriétés et d'autres comportements Héritage simple • L'héritage simple traduit un lien de type "est un" • factorisation des connaissances : la sous-classe hérite des propriétés de la classe mère • spécialisation: la sous-classe peut redéfinir des attributs ou des méthodes de la classe mère • extension: la sous-classe peut ajouter des nouveaux attributs ou des nouvelles méthodes VDe
Héritage multiple • Intérêt : dériver une nouvelle classe à partir de plusieurs classes mères • Complexité accrue car : • encore plus de partage d'informations • héritage des attributs, des méthodes et des relations entre classes • risque de conflits sur les noms lorsqu'on invoque une méthode • La hiérarchie d'héritage entre les classes est décrite suivant un graphe orienté sans cycle • Pas autorisé dans Java ! VDe
Le polymorphisme • Le polymorphisme traduit la capacité d'une méthode à prendre plusieurs formes • Principe : associer à un même message • pour des objets d'une hiérarchie de classes • l'exécution d'une méthode différente selon la classe d'appartenance de l'objet • Techniques • liaison statique • liaison dynamique VDe