Programmation orientée objet



Documents pareils
Programmer en JAVA. par Tama

Premiers Pas en Programmation Objet : les Classes et les Objets

Pour signifier qu'une classe fille hérite d'une classe mère, on utilise le mot clé extends class fille extends mère

Chapitre 10. Les interfaces Comparable et Comparator 1

Encapsulation. L'encapsulation consiste à rendre les membres d'un objet plus ou moins visibles pour les autres objets.

Une introduction à Java

Structure d un programme et Compilation Notions de classe et d objet Syntaxe

Introduction à Java. Matthieu Herrb CNRS-LAAS. Mars

INITIATION AU LANGAGE JAVA

Héritage presque multiple en Java (1/2)

LMI 2. Programmation Orientée Objet POO - Cours 9. Said Jabbour. jabbour@cril.univ-artois.fr

Java Licence Professionnelle CISII, Cours 2 : Classes et Objets

Auto-évaluation Programmation en Java

TP n 2 Concepts de la programmation Objets Master 1 mention IL, semestre 2 Le type Abstrait Pile

Cours intensif Java. 1er cours: de C à Java. Enrica DUCHI LIAFA, Paris 7. Septembre Enrica.Duchi@liafa.jussieu.fr

Cours 1: Java et les objets

F. Barthélemy. 17 mai 2005

TD/TP PAC - Programmation n 3

Corrigés des premiers exercices sur les classes

Langage et Concepts de ProgrammationOrientée-Objet 1 / 40

INTRODUCTION A JAVA. Fichier en langage machine Exécutable

Initiation à JAVA et à la programmation objet.

Généralités sur le Langage Java et éléments syntaxiques.

TP1 : Initiation à Java et Eclipse

Programmation par les Objets en Java

Java Licence Professionnelle CISII,

Java Licence Professionnelle Cours 7 : Classes et méthodes abstraites

Chapitre 2. Classes et objets

Langage Java. Classe de première SI

Synchro et Threads Java TM

RMI le langage Java XII-1 JMF

PROGRAMMATION PAR OBJETS

Tp 1 correction. Structures de données (IF2)

Langage et Concepts de Programmation Objet. 1 Attributs et Méthodes d instance ou de classe. Travaux Dirigés no2

Corrigé des exercices sur les références

as Architecture des Systèmes d Information

Page 1 sur 5 TP3. Thèmes du TP : l la classe Object. l Vector<T> l tutorial Interfaces. l Stack<T>

Un ordonnanceur stupide

P r ob lé m a t iq u e d e la g é n é r icit é. Pr in cip e d e la g é n é r icit é e n Ja v a ( 1 /3 )

Exceptions. 1 Entrées/sorties. Objectif. Manipuler les exceptions ;

Info0604 Programmation multi-threadée. Cours 5. Programmation multi-threadée en Java

Polymorphisme, la classe Object, les package et la visibilité en Java... 1

2 e édition JAVA 5 et 6. Jérôme Bougeault. TSoft et Groupe Eyrolles, 2003, 2008, ISBN :

Licence Bio Informatique Année Premiers pas. Exercice 1 Hello World parce qu il faut bien commencer par quelque chose...

Cours 1 : Introduction. Langages objets. but du module. contrôle des connaissances. Pourquoi Java? présentation du module. Présentation de Java

Threads. Threads. USTL routier 1

Polycopié Cours Programmation Orientée Objet sous Java Programme : Filière SMI S5

Chapitre VI- La validation de la composition.

Programmation en Java IUT GEII (MC-II1) 1

TD/TP PAC - Programmation n 3

Programmation Objet Java Correction

Apprendre la Programmation Orientée Objet avec le langage Java (avec exercices pratiques et corrigés)

RAPPELS SUR LES METHODES HERITEES DE LA CLASSE RACINE Object ET LEUR SPECIALISATION (i.e. REDEFINITION)

Plan du cours. Historique du langage Nouveautés de Java 7

C++ Programmer. en langage. 8 e édition. Avec une intro aux design patterns et une annexe sur la norme C++11. Claude Delannoy

Info0101 Intro. à l'algorithmique et à la programmation. Cours 3. Le langage Java

Introduction au langage Java

JAVA TD0. Prise en main du langage Environnement de base JAVA 1

La carte à puce. Jean-Philippe Babau

Java 1.5 : principales nouveautés

Remote Method Invocation (RMI)

Java Licence Professionnelle CISII,

Programmation avec des objets : Cours 7. Menu du jour

Aide mémoire UML & Java 1ère partie : Introduction. marc.lemaire@u-cergy.fr

Utilisation d objets : String et ArrayList

Introduction : les processus. Introduction : les threads. Plan

Java Licence professionnelle CISII,

Apprendre Java en 154 minutes

Généralités. javadoc. Format des commentaires. Format des commentaires. Caractères spéciaux. Insérer du code

TD3: tableaux avancées, première classe et chaînes

TP1. Outils Java Eléments de correction

ALGORITHMIQUE ET PROGRAMMATION ORIENTEE OBJET

Lambda! Rémi Forax Univ Paris-Est Marne-la-Vallée

INF 321 : mémento de la syntaxe de Java

Prénom : Matricule : Sigle et titre du cours Groupe Trimestre INF1101 Algorithmes et structures de données Tous H2004. Loc Jeudi 29/4/2004

TP, première séquence d exercices.

Cours d initiation à la programmation en C++ Johann Cuenin

Java c est quoi? Java pourquoi?

Exercices sur les interfaces

J2SE Threads, 1ère partie Principe Cycle de vie Création Synchronisation

Applet pour visualiser les variables «automate» notifiées

4. Groupement d objets

Programmation Orientée Objet application au langage Java Version Novembre 2007

SHERLOCK 7. Version du 01/09/09 JAVASCRIPT 1.5

Programmation Orientée Objet Java

La technologie Java Card TM

Exclusion Mutuelle. Arnaud Labourel Courriel : arnaud.labourel@lif.univ-mrs.fr. Université de Provence. 9 février 2011

Développement Logiciel

CPR Informatique. (poste 3159 ou 3164) Septembre 2002

Package Java.util Classe générique

Gestion distribuée (par sockets) de banque en Java

TD Objets distribués n 3 : Windows XP et Visual Studio.NET. Introduction à.net Remoting

Remote Method Invocation Les classes implémentant Serializable

Objets et Programmation. origine des langages orientés-objet

JADE : Java Agent DEvelopment framework. Laboratoire IBISC & Départ. GEII Université & IUT d Evry nadia.abchiche@ibisc.univ-evry.

RMI. Remote Method Invocation: permet d'invoquer des méthodes d'objets distants.

Java 7 Les fondamentaux du langage Java

Classes et Objets en Ocaml.

Génie Logiciel avec Ada. 4 février 2013

Java DataBaseConnectivity

Transcription:

Module 211 Programmation orientée objet Chapitre 3 : Les classes Les classes Membres de classe et membres d'instance Déclaration de classe Signature de classe Les champs Méthode de classe et méthode d'instance Les constructeurs Les initialiseurs statiques Classes abstraites Interfaces Les classes internes Gestion d'erreurs Les paquetages et la nomination Philippe Boulnois philippe.boulnois@free.fr

Les Classes Une classe est constituée de données : les champs et de comportements : les méthodes qui agissent sur ces données. Une classe permet de définir des objets. On peut dire d une classe qu elle est le modèle et que les instances sont des «réalisations» de ce modèle. Exemple : Cas d'un Compte Bancaire Quelles données doit contenir cet objet : - on ouvre un compte avec une certaine somme d argent que l on peut qualifier de mise initiale, - ce compte appartient à quelqu'un donc une donnée du compte correspond au nom du détenteur, - une autre donnée est le nom de la banque dans laquelle le compte est ouvert, - chaque compte possède un numéro attribué par la banque. Aux niveaux des opérations possibles : - retrait, - apport, - solde, - calcul d intérêt sur un prêt (méthode de classe), - demande de chéquiers, - liste des opérations effectuée dans le mois. Ceci n étant qu un exercice (et non un cas réel ) nous nous arrêterons là. Liste des champs et des méthodes pour gérer ( de façon élémentaire ) un compte bancaire Classe : CompteBancaire Champs : enseignedelabanque chaine de caractères String numeroducompte chaine de caractères String nomdudetenteur chaine de caractères String miseinitiale numérique Double Méthodes : verser() retirer() argument le montant du versement, retour le montant du solde argument le montant du retrait, retour le montant du solde Double/Double Double/Double

solde() retourne le solde rien/double simulationdeprêt() argument montant et nombre d années, tableau des annuités (annuité : capital remboursé, Double, int/ tableau de tableau de Double intérêt remboursé) demandechéquier() nombre de chéquiers tableau de chaines de caractères listedesoperations() date Remarques le champ miseinitiale pourrait être remplacée par un champ solde. La méthode solde() se contentant alors de retouner la valeur de ce champ. La classe CompteBancaire pourrait devenir abstraite et être sous classée suivant la banque où est ouvert le compte, alors le champ enseignedebanque devrait être une variable de classe. Héritage L héritage est une des caractéristiques essentielles des langages à objets. Les classes sont organisées en une hiérarchie dont le sommet est la classe Object. Toute classe hormis Object possède une (et une seule) super classe dont elle hérite. Toutes les classes héritent de la classe Object. Si B est sous classe d une classe A, on peut accéder et utiliser tous les champs (non privés) et toutes les méthodes (non privées) de la classe A, c est dans ce sens que l on dit que B hérite de A : la sous classe hérite les propriétés (les champs) et les comportements (les méthodes) de la super classe. L intérêt pratique d un tel mécanisme est une économie de code importante. Une sous-classe d une classe donnée est une «particularisation» de cette classe. Programmer en objet consistera donc d abord à construire des classes générales qui fournissent les données et les actions correspondant aux situations les plus générales, puis à sous-classer pour pouvoir construire des objets plus particuliers répondants à des situations spécifiques. Java, à la différence de C++, ne connaît que l héritage simple. Exemple : Nous allons "modéliser" un commutateur électrique. Nous trouvons deux caractéristiques à sa fonction : la puissance maximale qu il peut commuter : 100, 200, 500 watts et son état fermé/ouvert (autrement dit connexion établie ou non ), ce qui nous donne la classe suivante : Classe : Commutateur Champs : puissancedecommutation valeur entière int connexionetablie valeur booléenne boolean Méthodes : couper() rien rien allumer() rien rien

Il existe aussi des commutateurs électroniques plus sophistiqués que l on appelle gradateurs. En plus de la fonction «tout ou rien» des commutateurs ordinaires ils peuvent moduler la puissance délivrée. Il est donc logique de les voir comme des commutateurs d un type particulier et donc de définir la classe Gradateur comme sous classe de la classe Commutateur. Questions : 1) En vous inspirant de la classe Cercle définissez les classes Carre et Point : 2) Étudiez la définition de classe Gradateur que nous vous proposons et compilez et exécutez le code : Classe : Gradateur sous type de commutateur Champs : puissancedelivree valeur entière int Méthodes : augmenter() rien / rien diminuer() rien / rien Passons à l implémentation en Java de ces deux classes : public class Commutateur //champs d'instance int puissancedecommutation; boolean connexionetablie; // méthodes d'instance void allumer() connexionetablie = true; void couper() connexionetablie = false; public class Gradateur extends Commutateur //champs d'instance int puissancedelivree; // méthodes d'instance void augmenter() if (puissancedelivree < puissancedecommutation) puissancedelivree += 1; void diminuer() if (puissancedelivree > 0) puissancedelivree -= 1; else

connexionetablie = false ; import java.lang.*; public class Prog //méthode de classe main() point d'entrée du programme public static void main(string[] args) Class c = null; Gradateur ge = new Gradateur(); c=ge.getclass(); System.out.println("Classe de l'objet créé : " + c); System.out.println("Super classe de l'objet créé : " + c.getsuperclass()); /* La sous classe gradateur hérite des champs puissancedecommutation et connexionetablie de sa super classe, ainsi que des méthodes allumer() et couper()*/ System.out.println("Puissance par défaut : " + ge.puissancedecommutation); ge.puissancedecommutation = 250; System.out.println("Puissance affectée : " + ge.puissancedecommutation); System.out.println("Etat connexion par défaut? " + ge.connexionetablie); ge.allumer(); System.out.println("Etat connexion : " + ge.connexionetablie); ge.couper(); System.out.println("Etat connexion : " + ge.connexionetablie);

Membres de classe et membres d instance Les champs et les méthodes sont appelés membres de la classe. Ces membres peuvent être qualifiés de membres de classe ou de membres d instance. 1) champs et méthodes de classe Un champ de classe est lié à la classe, il aura la même valeur pour toutes les instances qui seront dérivées de la classe. Une méthode de classe ne peut agir que sur les champs de classe : en effet une méthode de classe est utilisable dès que la classe est chargée par le système, avant même toute instanciation de cette classe. Il est donc logique d empêcher une méthode de classe d utiliser méthodes ou champs d instance qui peuvent très bien ne pas (encore) exister. 2) champs et méthodes d instance Un champ d instance est lié à chaque objet créé. Chaque objet possède, en propre une copie de ce champ, la valeur du champ peut donc changer d une instance à l autre. Une méthode d instance peut modifier aussi bien des champs d instance que des champs de classe. Le qualificateur static Pour caractériser un champ ou une méthode de classe on le (la) préfixe, au moment de la déclaration, avec le modificateur static. L absence de ce modificateur caractérise évidemment un champ ou une méthode d instance. Exemple : Reprenons la classe Cercle précédemment définie : public class Cercle public static final double PI = 3.14159; private double rayon; Cercle(double r) rayon = r;

public double aire() return rayon * rayon * PI; Dans cette classe le champ rayon est un champ d instance, afin que chaque objet de type Cercle puisse détenir une valeur particulière pour le champ rayon. Par contre le champ Pi est un champ de classe (sa déclaration contient le qualificateur static ), car il est inutile que chaque objet de type Cercle «mémorise» la valeur de PI. Note : En fait la variable PI pourrait être encore «plus globale». En effet la valeur de PI «déborde» la simple classe de type Cercle, et peut être utilisée dans d autres classes de types géométriques, entre autres des classes définnissant des objets du domaine de la trigonométrie par exemple. La méthode aire() est une méthode d instance (indiquez pourquoi ), mais nous pourrions aussi définir une autre méthode de calcul de surface de Cercle qui soit une méthode de classe, l intérêt étant de pouvoir calculer une surface de cercle sans avoir à créer d objet Cercle; Remarque : Comme vous pourrez le constater en consultant la documentation toutes les méthodes de la classe Math sont des méthodes de classe. Il serait parfaitement inutile de devoir créer un objet de type Math pour pouvoir effectuer une élévation à la puissance (Math.pow(a,b)) ou calculer un sinus (Math.sin(a)). Polymorphisme et méthode d instance Quel intérêt peut il y avoir à définir des méthodes d'instance? En fait l implémentation de méthodes au niveau des instances autorise le polymorphisme : on peut envoyer un message à un objet sans avoir à connaître sa classe (son type). L objet contenant le code pourra répondre au message. Pour utiliser une méthode de classe il faut connaître la classe auquelle cette méthode appartient (car l'appel d'une méthode de classe se fait en préfixant le nom de la méthode par le nom de la classe), ce type de programmation est à l opposé de la programmation objet. Questions 1) Donnez une méthode de classe calculant la surface d'un Cercle 2) Donnez un exemple de polymorphisme à l'aide d'un objet de type Cercle, et un de type Carre. (Nous verrons un exemple plus complet dans le paragraphe sur les

transtypage de classe)

Déclaration de classe Chaque nouvelle classe définit un nouveau type de données en Java. Un programme Java est, en fait, un ensemble de définitions de classes. La classe est l unité élémentaire de programmation en Java. La déclaration se fait dans un fichier. Ce fichier devra porter comme nom celui de la classe qui y est déclarée suivi de l extension java. Plus précisément, une classe déclarée public ne peut être déclarée que dans un fichier dont le nom est celui de la classe suivi de l extension «java». En conséquence on ne peut déclarer qu une seule classe public par fichier. On peut déclarer en même temps d autres classes n ayant pas le modificateur public. Le compilateur produira alors un fichier de byte code par classe déclarée dans le fichier. On peut aussi déclarer dans un fichier plusieurs classes n ayant pas le modificateur public et enregistrer ce fichier sous un nom quelconque : à nouveau le compilateur produira autant de fichiers compilés qu il y a de classes déclarées dans le fichier source. Structure du fichier de déclaration de classe Une déclaration de classe est organisée de la façon suivante : En tête Déclaration optionnelle du paquetage d appartenance de la classe Importation optionnelle de paquetages Déclaration de classe Signature de la classe Déclaration optionnelle de champs de classe Déclaration optionnelle de champs d instance Déclaration optionnelle d initialiseurs statiques Déclaration optionnelle de constructeurs Déclaration optionnelle de méthodes de classe Déclaration optionnelle de méthodes d instance Déclaration optionnelle de classe(s) interne(s)

Nous allons examiner successivement les caractéristiques 1) déclaration/importattion de paquetages 2) signature de la classe 3) champs 4) méthodes 5) constructeurs Nous reviendrons plus tard sur les initialiseurs statiques et les classes internes. Les Paquetages Un fichier de classe peut comporter une déclaration de paquetage. S'il existe c'est lme premier élément du fichier (hormis des lignes mises en commentaire) : exemple : import java.awt.*; // importation du paquetage awt dans son intégralité grace au symbole '*' Les paquetages sont traités plus en détail plus loin. Cependant on peut résumer le paquetage comme étant un niveau de rangement situé hiérarchiquement au dessus des classes. On range les classes dans différents répertoires qui calquent la structure hiérarchiques des paquetages. Les paquetages apportent un niveau supplémentaire de contrôle d accès entre classes. Questions 1) Reprenez les exemples de classes Cercle, Carre et Prog utilisés dans la section précédente; Placez la classe Prog en tête du fichier, puis insérer les deux autres classes publiques (Cercle et Carre) dans ce même fichier; Sauvez ce fichier sous le nom Prog.java, puis essayer la compilation. Noter la réponse du compilateur. 2) Modifiez la déclaration des classes Cercle et Carre en retirant le modificateur public et essayez à nouveau de compiler le programme Prog.java. Que constatez vous? 3) Placez les deux classes Cercle et Carre dans un même fichier et nommez ce fichier d'un nom quelconque, compilez ce fichier, constatez que les fichiers Cercle.class et Carre.class sont effectivement produits, enfin compilez la classe Prog.java. 4) Recherchez dans la documentation Java les paquetages pour utiliser System.out.println() et Math.sqrt()

Signature d une classe [Modificateur] class nom [extends classe] [implements interface] code Exemple : public class Ellipse extends Cercle implements Runnable.. public est un modificateur d'accès (de visibilité) aux éléments de la classe Ellipse est le nom de la classe qui va être implémentée extends Cercle indique que la classe Ellipse est définie en tant que sous classe de la classe Cercle implements Runnable signifie que les méthodes définies dans l'interface Runnable seront implémentées par la classe Ellipse. Modificateurs de classe Modificateur d accès L accessibilité de la classe est déterminée par celle du paquetage : public Si le paquetage est accessible la classe l est aussi, si le paquetage ne l est pas la classe ne l est pas non plus. Pas de modificateur la classe n est accessible que dans son "amical" paquetage Concrètement les paquetages se traduisent par différents répertoires du système d'exploitation dans lesquels on range les classes. Les règles d accès entre paquetages sont alors celles définies au niveau des répertoires par le système d exploitation sous jacent. Autres modificateurs abstract final static La classe ne peut pas être instanciée La classe ne peut pas être sous-classée Voir le paragraphe sur les classes internes Classe déclarée abstraite Il n est pas possible d instancier une classe déclarée abstraite (modificateur abstract). Une classe doit être déclarée abstraite dès qu au moins une de ses méthodes est

déclarée abstraite. Une méthode est déclarée si : Elle n est pas implémentée Elle est implémentée, mais on la déclare abstraite malgré tout pour empêcher l instanciation de la classe en question, et obliger à sous classer pour pouvoir instancier. Une méthode abstraite ne peut être déclarée : private, static, final, native ou synchronized. Classe déclarée final On déclare une classe final pour empêcher qu elle puisse être sous-classée. Déclaration de sous-classe. Toute classe est sous-classe d une classe déjà existante. Si on n indique pas explicitement la classe parente à l aide de extends la classe est déclarée implicitement sous classe directe de la classe Object Exemples : public class Cercle.. signifie implicitement public class Cercle extends Object.. tandis que : public class Cercle extends FormesGeometriques... signifie explicitement que Cercle est une sous classe de la classe «FormesGeometriques», elle même sous classe d une autre classe... Déclaration d implémentation d interface

La signature d une classe peut également indiquer l implémentation d une (ou plusieurs) interface. Pour cela on fait précéder le nom de l interface implémentée par le mot-clef implements. Exemple : public class Cercle implements Runnable... exprime que la classe Cercle «affirme» implémenter le code nécessaire pour être «Runnable» ; Les interfaces sont étudiées plus loin. Transtypage de classe Chaque classe définissant un type de donnée le transtypage entre classes est envisageable, mais il n est possible qu entre classes ayant une relation hiérarchique : Le transtypage vers une superclasse est transparent, Le transtypage vers une sous-classe nécessite l usage de l opérateur de transtypage. Si le transtypage est effectué vers une classe qui n est pas une sous-classe, le système génére une Exception : ClassCastException. Exemples de transtypage. /******* Fichier Personne.java *********/ import java.util.*; public class Personne String nom; String prenom; Personne(String pm, String nm) prenom = pm; nom = nm; public void afficheetatcivil() System.out.println("Mr ou Mme "+prenom+ " "+nom); /******* Fichier Etudiant.java *********/ public class Etudiant extends Personne String universite; int annee;

Etudiant(String prenom, String nom) super(prenom, nom); public void convoquer() System.out.println("Convocat à l'examen");ion /******* Fichier Main.java *********/ public class Main public static void main(string[] args) Etudiant e1 =new Etudiant("Pierre", "Martin") ; Object o1 = e1 ; System.out.println(o1.getClass()) ; System.out.println(o1 instanceof Etudiant) ; System.out.println(o1 instanceof Personne) ; System.out.println(o1 instanceof Object) ; /*la méthode suivante est refusée par le compilateur car o1 est vu comme instance d'object */ o1.afficheetatcivil() ; /* Ici l'appel éthode "afficheetatcivil()" est acceptée car o1 est transtypé en type Personne ou Etudiant */ ((Personne)o1).afficheEtatCivil() ; ((Etudiant)o1).afficheEtatCivil() ; Object o2 = new Object(); /* Ici l'appel de méthode "afficheetatcivil()" est acceptée car o1 est transtypé en type Personne ou Etudiant, cependant comme l'objet o2 n'est pas de type Personne ni Etudiant l'envoi du message "afficheetatcivil() provoque une erreur à l'exécution */ ((Personne)o2).afficheEtatCivil() ; ((Etudiant)o2).afficheEtatCivil() ; Exemples de déclaration de classe Voici quelques exemples volontairement rudimentaires de déclaration de classes. Exemples : Une classe «vide» : public class Vide Une telle classe sera compilée avec succés. Pour qu une application autonome (Application autonome par opposition aux Applets ) puisse être exécutée par la machine virtuelle, il faut un point d entrée ; ce point d entrée est fourni par la méthode de classe dont la signature est la suivante : public static incrémentation main(string[ ] args)

(code) Voici donc le programme le plus simple que l on puisse faire : public class Vide public static incrémentation main(string[ ] args) Il faut l enregistrer sous le nom Vide.java ; on le compile avec la ligne de commande : > javac Vide.java le compilateur produit un fichier de byte code qu il nomme : Vide.class ; pour exécuter le byte code on entre la ligne de commande : > java Vide Voici maintenant un exemple de classe avec champs et méthodes de classe et d instance : public class Simple // champs de classe explicitement initialisžs static String progname = "philippe"; private static int nombremagique = 0; //champs d'instance sans initialisation explicite // ils seront initialisžs par le syst me String couleur; int quantitž; //mžthodes de classe public static nomduprogrammeur() System.out.println("L'auteur s'appelle : " + progname); //mžthodes d'instance public int getmagicnumber() return nombremagique; public String getcolor () return couleur; Ce fichier nommé Simple.java est compilable et donne le fichier de byte code Simple.class, pour autant il n est pas exécutable puisqu il ne comporte pas de point

d entrée. Par contre un autre programme peut maintenant utiliser le type «Simple» qui vient d être défini : class Prog1 public static incrémentation main(string[] args) Simple a; a = new Simple(); Simple.nomDuProgrammeur(); String s = a.getcolor(); System.out.println("La couleur est : " + s); Remarques : 1. Bien que ce programme (Prog1.java) n ait pour fonction que de faire appel à la classe Simple et à ses méthodes, sa structure est celle d une déclaration de classe (la classe Prog1), car en Java on ne peut écrire du code que dans le corps d une classe. 2. La classe Simple est accessible au programme (à la classe) Prog1 car aucune des deux ne précise un paquetage d appartenance en tête de fichier ; elles se trouvent donc, de façon automatique, toutes deux dans le paquetage anonyme par défaut fourni par le système. 3. L appel d une méthode de classe se fait en préfixant le nom de la méthode par le nom de la classe : Simple.nomDuProgrammeur() ; l appel de la méthode d instance se fait en préfixant le nom de la méthode par le nom de l instance : a.getcolor(). 4. Programmer en Java consiste à construire une classe pour chaque type d objet nécessaire dans un fichier séparé, puis à construire une classe avec un point d entrée et du code qui crée et manipule les objets instances des classes écrites par ailleurs. 5. La création d une instance de classe se réalise en utilisant l opérateur new : a = new Simple(); suivi du nom de la classe accompagné de parenthèse qui font penser à un appel de méthode. Cette méthode est un peu particulière, il s agit d un constructeur. 6. Les champs, à la différence des variables, n ont pas la nécessité d être initialisés, car ils sont initialisés au moment du chargement de la classe pour les champs de classe et au moment de la création de l objet pour les champs d instance. En revanche il est obligatoire d initialiser les variables locales qui elles n existent qu à l intérieur des méthodes.en fait on peut effectuer des opérations d initialisations plus sophistiquées pour les champs d instance à l aide des constructeurs. Questions 1) Indiquez les deux erreurs retournées à la compilation du code suivant : public class Cercle public static final double PI = 3.14159; double rayon;

Cercle(double r) this.rayon = r; public double perimetre(); public abstract double demiperimetre() return this.pi * this.rayon; public static void main(string[] args) Cercle c1 = new Cercle(12.0); System.out.println(c1.perimetre()); 2) Que va t il se passer si on compile le code suivant : public abstract class B static int origine = 1; int multpardeux(int nb) return nb * 2; static void afficheorigine() System.out.println("Origine vaut : "+origine); static void setorigine (int k) origine = k; 3) Que va t il se passer si maintenant on compile le code suivant : public class ProgB public static void main(string[] arg) B.afficheOrigine(); B.setOrigine(12); B.afficheOrigine(); B b = new B();

Les champs Le type d un champ est soit un des types primitifs (byte, short, int, long, char, int, double, boolean) soit un type référence (String, Integer, Frame ). Les champs peuvent être préfixés par des modificateurs d accès : Modificateurs d accès aux champs Modificateur private <<amical>> protected public Effet L'accès à ce champ est limité à la classe où il est déclaré L'accès à ce champ est limité au paquetage de «sa» classe Le champ est accessible dans le paquetage où il a été déclaré et dans les sous-classes de la classe, même si ces sous-classes sont dans des paquetages différents L'accessibilité est celle de la classe de déclaration du champ. Remarque :une méthode d une autre classe devra faire précéder le nom du champ du nom de la classe pour accéder à ce champ si c est un champ de classe et du nom de l instance si ce champ est un champ d instance. Autres modificateurs Modificateur Effet Ce modificateur caractérise un champ de classe, son absence static caractérise un champ d instance Ce modificateur empêche toute modification ultérieure de la final valeur du champ, si de plus le champ est static, il est considéré comme équivalent à une constante. Remarque :si le champ est un champ d instance (c. à d. qu il ne possède pas le modificateur static) la valeur ne pourra être changée, mais elle peut être différente d une instance à l autre c est pourquoi, dans ce cas on ne pourra l assimiler à une constante.

Les méthodes Vue de l intérieur une méthode peut être considérée comme une fonction : c est un bloc de code qui manipule des variables locales, utilisent des arguments passés en paramètres, accèdent à des champs ou les modifient. Les méthodes différent des fonctions notamment par leur localisation (elles sont encapsulées dans un objet, et leur appel qui ne peut se faire que relativement à cet objet (instance ou classe)). Une déclaration de méthode ne peut se faire que dans le corps d une classe. La spécification d une méthode est fournie par sa signature : [modificateur] type retourné nom (type et identificateur des paramètres) [throws type d exception levée]. Exemple : public static double aire(double rayon) ; Combinaisons pouvant faire partie d une signature de méthode : Modificateur Type Identificateur Paramètres Levée d exception De 0 à plusieurs 0 ou 1 Un seul De 0 à plusieurs Optionnel public static abstract final native private protected synchonized void type primitif tableau référence rien (pour les constructeurs) des identificateurs identiques sont possibles pour des méthodes différentes, si elles se distinguent par leurs paramètres typés throws (type de l exception) Modificateurs d accès de méthodes Modificateur Effet private La méthode n est accessible que dans le corps de la classe <<amical> L'accès à cette méthode est limité au paquetage de «sa» classe L'étendue est celui de l accès amical, auquel s ajoute l accès à protected partir de sous classes se trouvant dans des paquetages différents.

public L'accessibilité est celle de la classe de déclaration de la méthode. Autres modificateurs Une méthode déclarée final ne peut être redéfinie. Une méthode peut être explicitement déclarée final ou l être final implicitement si elle est déclarée dans une classe elle-même déclarée final. Permet des optimisations à la compilation. Une méthode synchronized obtient du système un verrou avant son début d exécution. Le verrou est celui de la classe synchronized pour une méthode de classe et celui de l objet pour une méthode d instance. Une méthode déclarée native indique qu elle implémente du native code dépendant du système sous-jacent, écrit la plupart du temps en C, C++ ou assembleur. Type de retour type primitif La méthode retourne une valeur d un des types primitifs type référence La méthode retourne une valeur qui est une référence à un objet void La méthode ne retourne rien La méthode est un constructeur Paramètres Les paramètres éventuels consistent en des couples de type/identificateur séparés par des virgules. À la différence de C++, la liste de paramètres d une méthode sans arguments est () et non (void). Clause throws La clause throws indique le type d exception que peut soulever la méthode. Exemple La méthode classe suivante peut soulever une «InterruptedException» lorsque la thread

reçoit le message «interrupt()» : public static void sleep(long millis) throws InterruptedException Surcharge. Java supporte la surcharge de méthode c est à dire que plusieurs méthodes d une même classe peuvent avoir le même identificateur, il suffit qu elles soient distinguables quant à leurs arguments, soit par le nombre de paramètres, soit par le type d au moins un des paramètres. Exemples /* Surcharge de méthodes : les deux méthodes "afficheetatcivil" ne se distinguent que par le nombre de leurs arguments */ public class Personne String nom; String prenom; public void afficheetatcivil(string nm) System.out.println("Mr ou Mme "+nm); public void afficheetatcivil(string nm, String pn) System.out.println("Mr ou Mme "+pn+ " "+nm); public static void main(string[] args) Personne p1 = new Personne(); p1.afficheetatcivil("martin"); p1.afficheetatcivil("martin", "Louise"); Un autre exemple de surcharge : public class Cercle public static final double PI = 3.14159; double rayon; Cercle(double r) rayon = r;

public double aire() return rayon * rayon * PI; public static double aire(double r) return r * r * PI; Questions /*Test de l'accès aux champs suivant leur qualification, dans la classe même tous les champs sont accessibles, depuis une autre classe les champs qualifiés de private ne sont pas accessibles*/ Voici quatre classes : AccesChamps, AccesDepuisAutreClasse, AccesChampsPackDiff, AccesChampsPackDiffParSsClasse, réparties dans deux paquetages différents : principal et different Le schéma ci-dessous vous donne une vue globale de la situation, notez que la classe AccesChampsPackDiffParSsClasse est une sous classe de AccesChamp et que la classe AccesChamps est importée dans AccesChampsPackDiff 1) Vérifiez que l'accès aux champs de puis la classe même est possible quelque soit le modificateur d'accès de ce champ

package principal; public class AccesChamps private int nb1; int nb2; protected int nb3; public int nb4; public static void main(string[] args) AccesChamps ac = new AccesChamps(); /* Accès aux champs depuis la classe même où ils sont définis*/ /* L'accès au champ nb1 qui est qualifié de private est possible ici car l'accès se fait depuis la classe où est déclaré le champ*/ ac.nb1 = 50; /* à fortiori l'accès aux champs qualifiés d'amical de protected ou de public est possible*/ ac.nb2 = 30; ac.nb3 = 20; ac.nb4 = 10; 2) Maintenant créez une autre classe "AccesDepuisAutreClasse" dans le même paquetage que "AccesChamps", et dans une méthode créez une instance de la classe "AccesChamps", et écrivez le code modifiant la valeur de chacun des champs (nb1, nb2, nb3, nb4) de cette instance. Compilez. Que constatez vous? 3) Mettez en commentaires la ligne "ac2.nb1 = 50;" et recompliez; cette fois ci vous obtenez deux fichiers de byte-code correspondants aux deux classes déclarées. Testez l'exécution de AccesChamps (qui contient un point d'entrée). Pouvez vous expliquer ce que retourne la machine virtuelle? 4) Nous allons maintenant déclarer deux autres classes appartenant à un autre le paquetage : le paquetage "different". Créez donc de suite le répertoire "different" au même niveau que le répertoire "principal" (dans lequel se trouve les fichiers AccesChamps.class et AccesDepuisAutreClasse.class- reportez vous au schéma si nécessaire pour visualiser la situation-). Dans le répertoire "different" déclarez une classe "AccesChampsPackDiff", insérez un code identique à celui de la classe "AccesDepuisAutreClasse". Compilez ce nouveau fichier : attention vous devez vous placer dan sle répertoire parent des répertoire principal et different et utiliser le chemin d'accès à la classe "AccesChampsPackDiff"; supposons que le répertoire parent de different et principal s'appelle EssaisModifAcces, vous devez taper quelque chose comme : EssaisModifAcces> javac different/acceschampspackdiff.java Que répond le compilateur? 5) Lancer la compilation après avoir effectuer les modifications de la réponses n 4, que

retourne le compilateur? 6) Dans le paquetage "different" déclarez la classe "AccesChampsPackDiffParSsClasse" en tant que sous classe de "AccesChamps" ; le code de cette classe est identique aux deux précédentes il s'agit de tenter l'accès aux champs de la classe "AccesChamps". Ajoutez le code suivant à la classe "AccesChampsPackDiffParSsClasse" et testez l'exécution du byte code : public static void main(string[] args) AccesChampsPackDiffParSsClasse acp = new AccesChampsPackDiffParSsClasse(); acp.testacces();

Méthode de classe et méthode d instance Méthode de classe Une méthode préfixée par le modificateur static est une méthode classe ; une telle méthode peut faire référence par leur nom simple aux champs ou méthodes de la classe, elle ne peut en aucun cas faire référence à un champ ou à une méthode d instance. Attention cela veut dire qu une méthode de classe ne peut pas manier directement un champ d instance ou une méthode d instance mais elle peut parfaitement créer des instances et envoyer des messages à ces instances : Si r est un champ d instance d un objet C1, une méthode de classe ne peut pas contenir : r = ( ou bien x = r +.) mais cette méthode de classe peut parfaitement contenir : C1.r = (ou bien x = C1.r +.) elle peut de même utiliser le résultat de l appel d une méthode d instance fait relativement à une instance. Comme dans l'exemple ci-dessous : public class Cercle public static final double PI = 3.14159; double rayon; Cercle(double r) rayon = r; public double aire() return rayon * rayon * PI; public static void main(string[] args) Cercle c1 = new Cercle(12.0); System.out.println(aire());

La compilation retourne : non-static method aire() cannot be referenced from a static context System.out.println(aire()); Si on remplace «System.out.println(aire())» par «System.out.println(c1.aire())» faisant ainsi référence à une instance, la compilation se termine sans erreur. Méthode d instance Si la méthode n est pas déclarée static elle est de fait une méthode d instance. Une méthode d instance est toujours appelée en faisant référence à une instance explicitement ou implicitement. /*Cet exemple illustre la référence explicite ou implicite à une instance pour l'envoi de message i.e. l'appel de méthodes*/ public class Cercle public static final double PI = 3.14159; double rayon; Cercle(double r) rayon = r; // référence implicite à l'objet lui même pour l'appel de la méthode demiperimetre public double perimetre() return demiperimetre() * 2; // référence implicite à l'objet lui même pour l'accés aux champs rayon et PI public double demiperimetre() return PI * rayon; // référence explicite à l'instance obligatoire pour l'appel de la méthode perimetre // car l'appel est fait à partir d'une méthode classe public static void main(string[] args) Cercle c1 = new Cercle(12.0); System.out.println(c1.perimetre());

Comme on le voit dans l exemple précédent il est plusieurs fois fait une référence implicite à l objet lui même dans le corps des méthodes ; en fait il est possible de faire une réfénce explicite à l objet grâce au syntagme this Quand this apparaît dans le corps d une méthode il faut le voir comme une référence à l instance à laquelle appartient la méthode en question. this et super En fait this permet l accès à l objet depuis l intérieur même de la classe de définition de cet objet Remarque : au moment où l objet est initialisé, le système initialise la variable this L emploi de this est obligatoire lorsque un paramètre de la méthode a le même nom qu un champ de l objet. Vous ne pouvez utiliser le nom simple du champ pour y faire référence car ce nom simple est «caché» par le nom de la variable. Vous préfixez alors le nom du champ du mot-clef this pour faire référence au champ : public void set radius( double rayon) this.rayon = rayon ; L'exemple précédent peut être écrit comme suit : public class Cercle public static final double PI = 3.14159; double rayon; Cercle(double r) this.rayon = r; // référence implicite à l'objet lui même pour l'appel de la méthode demiperimetre public double perimetre() return this.demiperimetre() * 2; // référence implicite à l'objet lui même pour l'accés aux champs // rayon et PI public double demiperimetre() return this.pi * this.rayon;

// référence explicite à l'instance obligatoire pour l'appel de la méthode perimetre // car l'appel est fait à partir d'une méthode classe public static void main(string[] args) Cercle c1 = new Cercle(12.0); System.out.println(c1.perimetre()); Comme nous allons le voir dans le paragraphe suivant super joue un rôle semblable à this au regard de la super classe. L'utilisation de super et le masquage de champ Le mot-clef super, lui, est nécessaire lors du masquage d un champ d une super classe. Si un champ d une sous-classe a le même identificateur qu un champ d une super classe, le champ de la super classe est masqué dans la sous classe. Dans ce cas pour faire référence au champ masqué de la super classe vous devez préfixer le nom du champ avec le mot-clef super. /*Utilisation de super et masquage de champs dans les sous classes A est la super classe de B qui elle même est super classe de C Le champ nombre est déclaré à chaque niveau de la hiérarchie, il est de ce fait masqué dans les sous classes */ public class A int nombre = 200; Dans l'exemple ci-dessous la méthode b.affiche() va retourner 100, car le champ b de la classe A est masqué, par le champ de même nom de la classe B public class B extends A int nombre; void affiche() System.out.println(this.nombre); System.out.println(super.nombre); public static void main(string[] args)

B b = new B(); b.nombre = 100; b.affiche(); Ci- après la classe C est sous classe de B, le champ nombre masque donc le champ de même nom de la classe B ainis que le champ nombre de la classe A. Dans la méthode affiche de la classe C, on fait afficher le champ nombre (this.nombre) de la classe C et et le champ nombre (super.nombre) de la classe B. De même dans la méthode "changevalueinsuperclasse" la valeur du champ nombre de la super classe B est modifié grace à l'emploi de "super" public class C extends B int nombre; void affiche() System.out.println(this.nombre); System.out.println(super.nombre); void changevalueinsuperclasse(int val) super.nombre = val; public static void main(string[] args) C c = new C(); c.nombre = -300; c.changevalueinsuperclasse(1234); c.affiche(); Cas particulier Cependant les choses se compliquent si le champ masqué est dans une super classe à un niveau plus haut dans la hiérarchie des classes, car il est interdit de «cascader» super (i.e. d écrire super.super) La solution est alors de transtyper le champ masqué avec le nom de la super classe. Ainsi dans l exemple précédent, il est impossible à partir de la classe C d accéder au champ nombre de la classe A en utilisant super.

Exemple : /*Le champ "nombre" de la super classe (B) est masqué par le champ de même nom de la classe Cc; il est possible cependant d'accéder au champ nombre de la classe A en utilisant le transtypage */ public class Cc extends B int nombre; void affiche() System.out.println("nombre ds Cc : "+this.nombre); System.out.println("nombre ds B : (accès avec super) "+super.nombre); System.out.println("nombre ds B : (accès par transtypage "+((B)this).nombre); System.out.println("nombre ds A : "+((A)this).nombre); void changevalueinsuperclasse(int val) super.nombre = val;// permet d'accéder au champ nombre de la classe B ((A)this).nombre = - val; public static void main(string[] args) Cc c = new Cc(); c.nombre = -300; c.changevalueinsuperclasse(1234); c.affiche(); Redéfinition de méthodes La redéfinition de méthode est différente de la surcharge. La surcharge caractérise l existence dans la même classe de plusieurs méthodes ayant le même identificateur mais une signature différente du fait de paramètres différents. La redéfinition caractérise, elle, l existence dans la sous classe d une méthode de même signature que celle d une méthode de la super classe. C est la méthode redéfinie qui sera appelée quand une instance de la sous classe recevra le message correspondant. On peut dire que la méthode redéfinie «masque» la méthode de même signature dans la super classe de la même façon qu un champ de la sous classe masque un champ de même nom de la super classe. La méthode du transtypage, que nous venons de voir dans le cas du masquage de champ,

ne «fonctionne» pas : c est toujours la méthode de la sous-classe qui est appelée. On peut néanmoins appeler la méthode redéfinie à l aide du mot-clef super : il suffit de préfixer l appel de la méthode du mot-clef super. Dans ce cas la recherche dynamique de méthode commence dans la super classe. Cependant, de même que pour le masquage de champs, cette syntaxe n est acceptable qu avec la classe immédiatement supérieure (c.à d. super.super n est pas permis) Note : si la méthode redéfinie est abstraite (abstract ) on dit alors qu elle est implémentée par la méthode de la sous-classe. Note : les méthodes déclarées private ou final ne peuvent être redéfinies : pour une méthode ayant le modificateur final dans sa signature c est évident puisque la signification de ce modificateur est d interdire la redéfinition. Pour le modificateur private c est un peu différent puisque la méthode déclarée private dans la super classe est inaccessible dans la sous classe! on peut donc écrire une méthode de même signature dans la sous classe mais cette méthode ne redéfinit pas, au sens propre, la méthode de la super classe qui est hors du champ de visibilité de la sous classe. Note : Une méthode qui redéfinit une méthode d une super classe ne doit pas entrer en conflit avec la méthode redéfinie par exemple en retournant un autre type de donnée. Exemple : On se souvient que le test d égalité de référence ne rend vrai que si les deux références pointent en fait sur le même objet. Java fournit une méthode equals() définie au niveau de la classe Object (et qui est donc héritée par tous les classes Java). Cette méthode, telle qu elle est définie dans la classe Object, est extrémement restrictive puisqu elle ne rend vrai que si les deux objets comparés sont en fait les mêmes ; autrement dit la méthode equals() se comporte exactement de la même façon que le test d égalité sur deux références! Mais la méthode equals() est redéfinissable à la différence de l opérateur d égalité == qui lui n est pas surchargeable. C est à celui qui définit une nouvelle classe que revient la charge de redéfinir la méthode equals(). L implémentation de cette méthode doit satisfaire aux règles des relations d équivalence : réflexive (xrx), symétrique(xry => yrx), transitive (xry et yrz => xrz) Questions

1) Dites ce que va produire l exécution de la ligne de commande : > java B si A et B sont définies par les classes ci-après : public class A int nombre = 200; void affiche() System.out.println("Methode affiche() de la classe A"); public class B extends A int nombre; void affiche() System.out.println("Methode affiche() de la classe B"); System.out.print("affiche() ds A : "); ((A)this).affiche(); public static void main(string[] args) B b = new B(); b.affiche(); 2) Modifiez la classe B précédente pour éviter le problème rencontré à la question précédente. 3) Redéfinir la méthode equals(), pour la classe Cercle ci-après : class Cercle private double rayon ; public void setrayon (double r) rayon = r ; public double aire() return rayon * rayon * PI ;

Les constructeurs Nous avons vu que pour instancier un objet, on utilise une instruction dont la syntaxe est : Nom_de_la_classe unevar = new Nom_de_la_classe(); La méthode "Nom_de_classe()" s'appelle un constructeur. L opérateur new crée l objet (il alloue l espace mémoire), mais il ne l initialise pas. C est au constructeur que revient ce rôle. Un constructeur est une méthode un peu particulière. Il est déclaré sans type et bien que sa signature ne comporte pas le mot void il ne retourne aucune valeur. Note : Le fait que l on puisse avoir plusieurs constructeurs pour une même classe permet d avoir des initialisations différentes pour un même type d objet. Ce que ne permet pas l initialisation réalisée sous forme d une simple affectation des champs d instance. Note : Il est tout à fait possible de définir et d utiliser une classe sans jamais construire d instance de cette classe. Les champs de classe doivent donc être initialisés en dehors de tout appel à un constructeur. C est le compilateur qui génère, de façon transparente, une méthode d initialisation de ces champs pour chaque classe. Cette méthode d'initialisation est appelée une seule fois, au moment du chargement de la classe dans l espace de travail. Constructeur implicite Une classe peut être implémentée sans qu aucun constructeur explicite ne soit écrit, le système fournit alors un constructeur implicite qui effectue une intialisation par défaut pour chaque type de champs de la classe. Les valeuirs par défaut utilisés par le constructeur sont : byte (byte) 0 short (short)0 int (int)0

long (long)0 double (double)0.0 char \u0000 boolean false reference null La seule action de ce constructeur implicite sera de faire un appel au constructeur sans argument de la super classe. Un constructeur n est pas un membre de la classe, il n est donc pas hérité, et ne peut être redéfini par un constructeur d une sous-classe. Note : Si le corps d un constructeur d une sous-classe ne commence pas par un appel à un autre constructeur, le compilateur suppose implicitement qu il y a un appel au constructeur, sans argument, de la super classe ; Note : Si la classe est déclarée public le constructeur par défaut est considéré comme public, sinon l accès au constructeur est celui défini par une absence de modificateur d accès. Les constructeurs supportent les mêmes modifications d accès : public, protected, (amical), private que les méthodes. Pour supprimer la possibilité de créer des instances, il suffit de déclarer au moins un constructeur (ce qui empêche le système de créer le constructeur par défaut) et (s'ils existent) de déclarer les autres constructeurs private. Ceci permet de contrôler la création d instance, comme le montre l exemple suivant : Le constructeur de la classe A est privé, il est donc inaccessible depuis une autre classe. En passant par la méthode makeinstance() une classe peut obtenir une instance de A, mais la méthode makeinstance() peut de plus contrôler le nombre d'instance produite, contrôle qu il n est pas possible de réaliser au niveau du constructeur. Ici une seule instance de la classe A est autorisée. Évidemment makeinstance() doit être une méthode de classe, pour pouvoir être exécutée en l'absence d'instance. public class A static private int compteur = 0; private A() System.out.println("Instance n : " +compteur); public static A makeinstance()

if (compteur++ < 1) return new A(); else return null; À noter l usage de try/catch pour la gestion de l exception qui se produit lorsque la méthode makeinstance() renvoie null public class B public static void main(string[] args) A a = A.makeInstance(); try A a2 = A.makeInstance(); catch(java.lang.nullpointerexception e) System.out.println("Plus d'instance disponible!"); Note : L usage de ce procédé peut être par exemple de fixer un nombre maximum d instances possibles au regard de la puissance de la machine utilisée. Surcharge de constructeur On peut définir autant de constructeurs que nécessaire pour une classe donnée. Évidemment, comme pour la surcharge de méthodes, les différents constructeurs d une classe doivent se distinguer par leurs paramètres. L intérêt des constructeurs multiples est renforcé par le fait qu un constructeur peut en appeler un autre. Ce qui autorise, pour des objets complexes, des initialisations «en cascade», permettant une économie de code. L appel d un autre constructeur se fait à l aide du mot-clef this employé sous forme d un appel de méthode : this(). La sélection du constructeur appelé se fait sur les arguments passés en paramètre. Il est nécessaire que l appel this() soit la première instruction du constructeur appelant, car c est au sein du constructeur que se fait l initialisation des champs (voir chaînage d appel des constructeurs). public class Personne

String nom; String prenom; String adresse; Personne(String nom) this.nom = nom; // nécessaire pour éviter le masquage du champ par la variable System.out.println("Appel constructeur 1 param"); Personne(String nom, String prenom) this(nom); // appel du constructeur à un argument this.prenom = prenom; // this pour éviter le masquage du champ par la variable System.out.println("Appel constructeur 2 param"); Personne(String nom, String prenom, String adresse) this(nom, prenom); // appel du constructeur à deux arguments this.adresse = adresse; System.out.println("Appel constructeur 3 param"); /* utlisation des arguments fournis sur la ligne de commande sans vérification*/ public static void main(string[] args) Personne p = new Personne(args[0], args[1], args[2]);// appel construct à 3 param System.out.println("Nom : "+ p.nom); System.out.println("Prenom : "+ p.prenom); System.out.println("Adresse : "+ p.adresse); L exécution donne : > java Personne Martin Paul Rennes Appel constructeur 1 param Appel constructeur 2 param Appel constructeur 3 param Nom : Martin Prenom : Paul Adresse : Rennes Chaînage de constructeurs Nous venons de voir qu un constructeur peut appeler un autre constructeur de la même classe à l aide du mot-clef this(), il peut aussi appeler un constructeur de la super classe en utilisant le mot-clef super().

Comme pour this(), super() doit être la première instruction du constructeur et la sélection du constructeur de la super classe (s il en existe plusieurs) se fera sur les arguments passés dans super(). Le chaînage implicite. Si le constructeur ne fait pas appel à un constructeur de la super classe c est Java qui le fait. Java choisit alors d appeler le constructeur de la super classe sans argument. Si, dans la super classe, vous n avez défini aucun constructeur, les choses se passent bien car Java définit, alors, un constructeur implicite sans argument à votre place (constructeur dont la fonctionnalité est d appeler le constructeur sans argument de la super classe). Mais si, dans la super classe, vous avez défini des constructeurs, Java ne fournit plus le constructeur par défaut sans argument, constructeur qui va être appelé depuis le constructeur de la sous-classe. Si dans les constructeurs que vous avez défini il n'y en a pas un qui soit sans arguement le compilateur refuse alors de compiler la sous classe. Exemple : public class A A() System.out.println("Exécution du constructeur de A sans arg"); public class B extends A public static void main(string[] arg) B b = new B(); L exécution de la commande : >java B donne : >E xé c u t i o n d u c o n s t r u c t e u r d e A s a n s a r g La création d une instance de B provoque l appel au constructeur implicite de B qui lui même appelle le constructeur sans argument de A, comme le montre l affichage sur la console. Remarque : une classe déclarée public qui n a pas de constructeur explicite reçoit de la part de Java un constructeur sans argument implicite déclaré public) ; si vous

ne voulez pas que cette classe public soit instantiable par toutes les autres classes, vous devez créer au moins un constructeur (avec arguments) qui ne soit pas public (cela empêche Java de fournir le constructeur implicite qui serait public). Par exemple l insertion d un constructeur déclaré «amical» (pas de modificateur) empêche la fourniture d un constructeur par défaut et ce constructeur étant déclaré «amical» ne peut être utilisée que depuis le paquetage de la classe. Questions 1) En reprenant la classe A de l'exemple modifiez le constructeur, en lui donnant un argument quelconque, compilez la classe B, que constatez vous? Modifiez la classe B en définissant un constructeur qui fasse appel explicitement au constructeur sans argument de A ; Compilez B. Dans la classe B ainsi obtenu supprimez l'appel au constructeur de la super classe réalisé par la ligne super(); Compilez et exécutez que constatez vous? Maintenant modifiez le constructeur de la classe A en lui ajoutant un argument, compilez 2) En partant de la définition de la classe Cercle, construisez une classe CerclePositionnable; Les données supplémentaires d'un objet CerclePositionnable étant la définition des coordonnées de son centre. 3) En partant de la classe CerclePositionnable construite à la question précédente déclarez un constructeur sans argument qui utilise le constructeur avec arguments, pour définir un objet Cercle avec les valeurs par défaut rayon = 1, position (0,0)