Développement
Logiciel GInfo +GP S4
Affectation et
comparaison d’objets
Affectation d’objets
Supposons que nous disposions d’une classe Point possédant un constructeur à
deux arguments entiers et considérons ces instructions.
Après leur exécution,
… on aboutit à cette situation :
Point a , b ;
….
a = new Point ( 3, 5);
b = new Point ( 2, 0);
….
Affectation d’objets
Exécutons maintenant l’affectation : a = b.
…
Point a , b ;
….
a = new Point ( 3, 5);
b = new Point ( 2, 0);
….
a = b;
….
Affectation d’objets
Exécutons maintenant l’affectation : a = b.
…
Point a , b ;
….
a = new Point ( 3, 5);
b = new Point ( 2, 0);
….
a = b;
….
Donc, a et b désignent le même objet,
et non pas deux objets de même valeur
Constructeur de copie
Un constructeur de copie est un constructeur recevant un
paramètre du même type que la classe.
Le rôle du constructeur de copie est de copier les valeurs de tous les
attributs de l'objet passé en paramètre.
Exemple:
public Point (Point P) {
this . x = P.x ;
this . y = P.y ;
}
Cela permet de construire une instance à partir d'une autre.
Affectation d’objets
Donc
…
Point a , b ;
….
a = new Point ( 3, 5);
b = new Point ( 2, 0);
….
a = new Point (b);
….
Ainsi, a et b désignent deux objets
différents avec les mêmes valeurs
La notion de clone
L’affectation de variables de type objet se limite à la recopie de références. Si on le
souhaite, on peut bien entendu effectuer explicitement la recopie de tous les champs
d’un objet dans un autre objet de même type.
public Point copie() {
Point p = new Point (this . x , this . y );
return p ;
public Point copie() {
}
return new Point (this . x , this . y );
}
Cette démarche est utilisable tant que la classe concernée ne comporte pas de champs
de type classe.
La notion de clone
La copie profonde d’un objet : on recopie la valeur des champs d’un type primitif.
Mais pour les champs de type objet, on crée une nouvelle référence à un autre
objet du même type avec les mêmes valeurs.
La copie superficielle d’un objet : on se contente de recopier la valeur de tous ses
champs, y compris ceux de type objet.
Affectation d’objets
Quels résultats fournit ce programme ?
class Entier{
private int a ;
[Link] ("n1 == n2 est " + (n1 == n2)) ;
public Entier (int b) { a = b ; }
public void incr (int d) { a += d ; } n1 = n2 ;
public void imprime () { [Link] (a) ; } [Link](12) ;
[Link] ("n2 = ") ;
public static void main (String args[]) { [Link]() ;
Entier n1 = new Entier (2) ; [Link] ("n1 = ") ;
[Link] ("n1 = ") ; [Link]() ;
[Link]() ; [Link] ("n1 == n2 est " + (n1 == n2)) ;
Entier n2 = new Entier (5) ; }
[Link] ("n2 = ") ; }
[Link]() ;
[Link](3) ;
[Link] ("n1 = ") ;
[Link]() ;
Surcharge
Surcharge
La surcharge survient lorsque on a deux méthodes(constructeur) ou plus du
même nom mais qui ne prennent pas les mêmes arguments.
• Exemple:
public int somme (int a, int b){
return a+b;
}
public int somme (int a, int b, int c){
return a+b+c;
}
Surcharge & Conversions
La conversion (cast) vers un type dont la taille de la représentation est plus grande
ou égale se font automatiquement sans avoir besoin d’être spécifié.
public void printVal (double val){
[Link]("La valeur est:"+val) ;
}
Surcharge
Quels résultats fournit ce programme ? class B{
class A{ public static void main(String args[]) {
public void f(int n,float x) { A a = new A();
[Link]("f(int n,float x) n="+n+"x="+x); a.g();
} [Link]("--- Dans main de B");
private void f(long q,double y) { int n=1; long q=12;
[Link]("f(long q,double y) q="+q+"y="+y);
} float x=1.5f; double y=2.5;
public void f(double y1,double y2) { a.f(n,q);
[Link]("f(double y1,double y2) y1="+y1+"y2=" +y2); a.f(q,n);
} a.f(n,x);
public void g() { a.f(n,y);
int n=1; long q=12; }
float x=1.5f; double y=2.5; }
[Link]("--- Dans g");
f(n,q);
f(q,n);
f(n,x);
f(n,y);
}
}
Statique
Attributs statiques
Un attribut statique est un attribut qui est commun à tous les objets de la classe.
→ On peut par exemple crée un compteur du nombre d'instances de classe.
class Test{
public static int cpt;
public Test() {
cpt++;
[Link]("Nombre d'instances crées"+ cpt);
}
}
L'avantage des attributs statiques est que vous pouvez y accéder même si vous n'avez pas
créé d'instance de la classe. Ainsi, vous pourrez écrire si vous le souhaitez n'importe où ceci :
[Link]("Nombre d'instances crées"+ [Link]);
Méthodes statiques
Une méthode statique est une méthode qui peut être appelée même sans avoir instancié
la classe. Une méthode statique ne peut accéder qu'à des attributs et méthodes statiques.
class Test{
public static int cpt;
public Test() {
cpt ++;
}
public static void nbrInstances() {
[Link]("Nombre d'instances crées"+ cpt);
}
}
Vous pouvez sans avoir instancié la classe accéder à la méthode statique en tapant ceci :
[Link]();
Scanner
Scanner
La classe Scanner permet de lire les entrées de différents types de
données, comme les types primitifs et les chaînes de caractères, à partir de
diverses sources telles que l’entrée standard (clavier), les fichiers, les chaînes,
et plus encore.
Pour utiliser la classe Scanner, il faut créer un objet de la classe et utiliser l'une
de ses méthodes
Scanner sc = new Scanner([Link]);
int a = [Link]();
NB: Pour utiliser la classe Scanner, il faut d’abord l’importer :
import [Link];
Scanner
Les méthodes de Scanner
Méthode Description
nextBoolean() lit une valeur booléenne à partir du clavier
nextByte() lit un entier (byte) à partir du clavier
nextDouble() lit un réel (double) à partir du clavier
nextFloat() lit un réel (double) à partir du clavier
nextInt() lit une valeur entière (int) à partir du clavier
nextLine()/next() lit une chaine de caractère à partir du clavier
nextLong() lit un entier (long) à partir du clavier
nextShort() lit un entier (short) à partir du clavier
Destruction des objets
L’espace mémoire occupé par tout objet qui n’est plus référencé est
automatiquement récupère au bout d’un certain temps par le Garbage
Collector (ramasse-miette).
Il est possible, pour toute classe, d’écrire une méthode finalize,
automatiquement invoquée lorsqu’un objet va être récupéré par le Garbage
Collector.
Héritage
Notion d’héritage
Définition de deux classes:
Etudiant Employe
Nom Nom
CIN CIN
anneeNaiss anneeNaiss
CNE prixHeure
note[] nbrHeure
age() age()
Limites: moyenne() salaire()
-Duplication de code.
-Une modification faite sur un attribut (ou méthode) commun doit être refaite
dans les autres classes.
Notion d’héritage
Définition de trois classes: Personne Etudiant Employe
Nom Nom Nom
CIN CIN CIN
anneeNaiss anneeNaiss anneeNaiss
CNE prixHeure
age() note[] nbrHeure
age() age()
moyenne() salaire()
Héritage
L’héritage permet d’écrire une classe B
– qui se comporte dans les grandes lignes comme la classe A
– mais avec quelques différences sans toucher ni copier le code source de A
Le code de B ne comporte que ce qui a changé par rapport au code de A
On peut par exemple
– ajouter de nouvelles méthodes ou des attributs.
– modifier certaines méthodes ou des attributs.
• L’héritage existe dans tous les langages de POO.
Notion d’héritage
Définition de trois classes: Super-classe
Personne
Nom
CIN
Héritent de
anneeNaiss
age()
Etudiant Employe
CNE prixHeure
note[] nbrHeure
Solution : moyenne() salaire()
+ Réutilisation du code sans le toucher ou le copier . Sous-classes
+ Une seule modification pour les attributs ( ou méthodes) en commun .
Héritage : Vocabulaire
- La classe B qui hérite de la classe A s’appelle une classe fille ou sous-classe
- La classe A s’appelle une classe mère, classe parente ou super-classe
Héritage
– Pour signifier qu'une classe fille hérite d'une classe mère, on utilise le mot clé extends : class
fille extends mere .
– En java, toutes les classes sont dérivée de la classe Object, et chaque classe à une et une seule
classe mère (pas d’héritage multiple).
– Les sous-classes n'ont pas accès aux membres private de leur classe mère.
Remarque: les attributs privés de la classe mère sont bien hérités par les classes filles, mais ils ne
sont accessibles qu'à travers les accesseurs et/ou les méthodes de la classe mère qui les utilise.
- Si on veut qu'un attribut ou une méthode soit encapsulé pour l'extérieur mais qu'il soit
accessible par les sous-classes, il faut le déclarer protected à la place de private.
Héritage
class Personne { Personne
private String nom,cin; Nom
CIN
private int anneeNaiss;
anneeNaiss
}
age()
class Etudiant extends Personne {
private String cne;
private float note[];
……
}
Etudiant Employe
class Employe extends Personne { CNE prixHeure
private float prixHeure ,nbrHeure; note[]
nbrHeure
…….. moyenne() salaire()
}
Héritage
Exemple d’héritage : 2ème cas
class Ville {
1er cas public String nom;
class Ville { public int nbrHab;
private String nom; }
private int nbrHab; class Capitale extends Ville {
} private String pays;
public void afficheCapitale() {
class Capitale extends Ville { [Link]( nom + " est la Capitale de "+ pays );
private String pays; }
public void afficheCapitale() { }
[Link]( nom + " est la Capitale de "+ pays );
}
}
Héritage
4ème cas
3ème cas public class Ville {
public class Ville { private String nom;
protected String nom; private int nbHab;
protected int nbHab; public String getNom() {
} return nom;
public class Capitale extends Ville { }
public int getNbHab () {
private String pays;
return nbHab;
public void afficheCapitale() {
}
[Link]( nom + " est la Capitale de "+ pays );
}
}
public class Capitale extends Ville {
} private String pays;
public void afficheCapitale() {
[Link]( getNom() + "est la Capitale de "+ pays );
}
}
Attribut Méthode Classe
L’attribut est visible par n'importe quelle classe du package La méthode est visible de n'importe quelle Peut-être dérivée par des
public
ou extérieure au package. classe. classes de tout package
L’attribut n'est visible que dans la classe courante. La méthode n'est applicable que dans la classe
private Pas de sens
( non visible même dans les classes filles ) courante.
La méthode n'est utilisable que par la classe, ses
L’attribut n'est visible que par la classe, ses filles et les autres sous classes du même package ou de packages
protected Pas de sens
classes du package ainsi que leurs filles différents et les autres classes du package ainsi
que leurs filles
L’attribut est dit "attribut de classe".
La méthode est dite "méthode de classe" . Elle
Si l’attribut d'une instance de cette classe est modifié,
est définie une seule fois pour toutes les
toutes les instances de l'objet sont automatiquement
instances. Il est possible de l'appeler
modifiées. Ainsi, l’attribut ne dépend pas de l'instance
directement par la classe:
static courante mais de la classe. Il est possible d'y accéder Pas de sens
[Link]éthode();
directement par la classe: [Link]été
ou on peut l’appeler par l’objet
ou on peut accéder par l’objet:
MaClasse mc=new MaClasse();
MaClasse mc=new MaClasse();
[Link]éthode ();
[Link]été
L’attribut est non modifiable dans l'instance courante. Elle
La méthode ne peut être surchargée dans une La classe ne peut pas avoir
final doit donc être initialisée. Si on ajoute le mot clé "static", la
sous-classe de classes filles.
variable est une constante de classe: static final int i=2;
Sous-type
Un objet de sous-classe peut être affecté à un objet de classe Mère
Les sous-classes d’une classe B sont des sous-types de A
En effet, si B hérite de A, tout B est un A donc on peut ranger un B dans un objet de type A.
Par exemple :
Ville v = new Capitale();
Important : L’affectation [mère → sous-classe] n’est pas possible
Constructeur
Chaque instance est munie de deux références particulières :
• this réfère l’instance elle-même.
• super réfère la partie héritée de l’instance.
La première instruction d’un constructeur peut être un appel:
• à un constructeur de la classe mère : super(...)
• ou à un autre constructeur de la classe : this(...)
Constructeur
Interdit de placer this() ou super() ailleurs qu’en première instruction d’un constructeur .
class Personne{
protected String nom,prenom;
protected int anneeNaiss;
public Personne(String nom, String prenom, int anNaiss){
[Link] = nom;
[Link] = prenom;
[Link] = anneeNaiss;
}
}
class Prof extends Personne{
private String matiere;
public Prof(String nom, String prenom, int anneeNaiss, String matiere) {
super(nom,prenom,anneeNaiss);
[Link] = matiere;
}
}
Constructeur
Si la première instruction d’un constructeur n’est ni super(...), ni this(...), le
compilateur ajoute au début un appel implicite super() au constructeur sans
paramètre de la classe mère (erreur de compilation s’il n’existe pas !)
Un constructeur de la classe mère est toujours exécuté avant les autres
instructions du constructeur.
Redéfinition des méthodes
class B { class B {
void m(){ void m(){
[Link]("méthode m de B");
[Link]( "méthode m de B");
} }
} }
class D extends B{ class D extends B{
} void m(){
…. [Link]( "méthode m de D");
B b = new B(); }
D d = new D();
b.m(); //méthode m de B }
d.m(); //méthode m de B ….
B b = new B();
D d = new D();
b.m(); //méthode m de B
d.m(); //méthode m de D
Redéfinition des méthodes
class Personne{
protected String nom,prenom;
protected int anneeNaiss;
public Personne(String nom, String prenom, int anNaiss){
[Link] = nom;
[Link] = prenom;
[Link] = anneeNaiss;
}
public void afficher(){
[Link]("Nom : "+nom+", prenom : "+prenom+ ", année de naissance : "+anneeNaiss);
}
}
class Prof extends Personne{
private String matiere;
public Prof(String nom, String prenom, int anneeNaiss, String matiere) {
super(nom,prenom,anneeNaiss);
[Link] = matiere;
}
public void afficher(){
[Link]("Nom:"+nom+",prenom:"+prenom+",année de naissance:"+anneeNaiss +",matiere:"+matiere);
}
}
Redéfinition des méthodes
class Personne{
protected String nom,prenom;
protected int anneeNaiss;
public Personne(String nom, String prenom, int anNaiss){
[Link] = nom;
[Link] = prenom;
[Link] = anneeNaiss;
}
public String toString(){
return "Nom : "+nom+", prenom : "+prenom+ ", année de naissance : "+anneeNaiss;
}
}
class Prof extends Personne{
private String matiere;
public Prof(String nom, String prenom, int anneeNaiss, String matiere) {
super(nom,prenom,anneeNaiss);
[Link] = matiere;
}
public String toString(){
return super. toString()+",matiere:"+matiere;
}
}
Redéfinition des méthodes
Ne pas confondre la redéfinition avec la surcharge :
• Redéfinition : même type de retour et mêmes paramètres.
• Surcharge : au moins les paramètres doivent être différents,
en plus de type de retour
Opérateur instanceof
L’opérateur instanceof permet de savoir à quelle classe appartient une instance :
class B{ …}
class C {…}
class D extends B{…}
B b = new B();
C c = new C();
D d = new D();
b instanceof B // true
b instanceof D // false
d instanceof B // true
d instanceof D // true
c instanceof B // erreur de compilation :impossible de comparer C avec B
Questions