Les classes et les objets Les données finales class A { … private final int n = 20 ; // la valeur de n est définie dans sa déclaration … } class A { public A (int nn) {n= nn; } // la valeur de n est définie par le constructeur private final int n; } Remarque : un champ déclaré final doit être initialisé au plus tard par un constructeur
Les classes et les objets La notion de clone class Point { public Point (int abs, int ord) { x = abs; y = ord; } public Point copie () // renvoie une référence à un Point { Point p = new Point (x,y); p.x = x; p.y = y; return p; } private int x,y; } … Point a = new Point (1,2); Point b = a.copie (); // b est une copie conforme de a Remarques : - copie superficielle != copie profonde - a==b indique vrai si a et b possède la même référence
Les classes et les objets Les objets membres (1) class Point { private int x,y; public Point (int x, int y) { this.x; this.y=y; } public void affiche () {System.out.println (" Je suis un point de coordonnees " + x + " " +y); } public int getX() { return x;} public int getY() {return y;} public void setX (int x) { this.x = x;} public void setY (int y) { this.y = y;} }
Les classes et les objets Les objets membres (2) class Cercle { private Point c; // centre du cercle private float r ; // rayon du cercle public Cercle (int x, int y, float r) { c=new Point (x,y); this.r = r; } public void affiche () {System.out.println (" Je suis un cercle de rayon "+ r); System.out.println(" et de centre de coordonnees " + c.getX() + " " + c.getY()); } public void deplace( int dx, int dy) { c.setX( c.getX() + dx); c.setY(c.getY() + dy);} }
Les classes et les objets Les objets membres (3) public class TstCerc { public static void main (String args[]) { Point p = new Point (3,5); p. affiche(); Cercle c = new Cercle (1,2,5.5); c.affiche();} } Je suis un point de coordonnees 3 5 Je suis un cercle de rayon 5.5 et de centre de coordonnees 1 2
Les classes et les objets Les classes internes Une classe peut être définie à l’intérieure d’une autre classe ; on parle alors de classe interne. Un objet d’une classe interne est toujours associé, au moment de son instanciation, à un objet d’une classe externe dont on dit qu’il lui a donné naissance. Un objet d’une classe interne a toujours accès aux champs et méthodes (même privés) de l’objet externe lui ayant donné naissance; Un objet de classe externe a toujours accès aux champs et méthodes (même privés) d’un objet d’une classe interne auquel il a donné naissance.
Exemple Class Cercle { class Centre // définition interne à Cercle { private int x, y; public Centre (int x, int y) { this.x = x; this.y = y; } } private Centre c; private double r; public Cercle (int x, int y, double r) { c = new Centre (x, y); this.r = r; } public void deplace (int dx, int dy) { c.x += dx; // ici, on a bien accès à x et y c.y += dy; }
La classe String Généralités La classe String permet de manipuler des chaînes de caractères. String ch1 = new String(); // ch1 contient la référence à une chaîne vide String ch2 = new String (" hello "); // ch2 contient la référence à une chaîne contenant // la suite " hello " String ch3 = new String (ch2); // ch3 contient la référence à une chaîne copie de ch2, //donc contenant « hello ». String ch4 = "bonjour "; // ch4 contient la référence à la chaîne « bonjour » Un objet de type String n ’est pas modifiable.
La classe String Opérations (1) Accès aux caractères d ’une chaîne : charAt String ch = " bonjour " ; ch.charAt(0) correspond au caracère ‘ b ’ Concaténation de chaînes String ch1 = " Le langage "; String ch2 = " java "; String ch = ch1 + ch2; Conversions des opérandes de l ’opérateur + int n = 26; String titre = " resultat " ; String resul = titre + 26; L ’opérateur += String ch = " bonjour " ; ch += " monsieur " ; ch désigne la chaîne " bonjour monsieur " La chaîne " bonjour " devient candidate au ramasse-miettes.
La classe String Opérations (2) La méthode compareTo : comparaison lexicographiques chaîne1.compareTo(chaîne2) Elle fournit : - un entier négatif si chaîne1 arrive avant chaîne2, - un entier nul si chaîne1 et chaîne2 sont égales - un entier positif si chaîne1 arrive après chaîne2. Remplacement de caractères String ch = " bonjour "; String ch1 = ch.replace(‘ o ’, ’a ’); ch n ’est pas modifiée. Ch1 contient " banjaur ".
La classe String Opérations (3) Extraction de sous-chaines Tous les caractères depuis une position donnée String ch = « anticonstitutionnellement »; String ch1 = ch.substring (4); // ch n ’est pas modifiée // ch1 contient " onstitutionnellement " Tous les caractères compris entre deux positions données String ch =" anticonstitutionnellement "; String ch1 = ch.substring (4,12); // ch n ’est pas modifiée // ch1 contient "constitution " Passage en majuscules ou en minuscules String ch " LanGaGE_3 "; String ch1 = ch.tolowerCase(); // ch est inchangée ; c1 contient " langage_3 " String ch2 = ch.toUpperCase(); // ch2 contient " LANGAGE_3"
Conversions entre chaînes et types primitifs Conversion d ’un type primitif en une chaîne Int n = 427; String ch = String.valueOf(n); ch = " " + n; Conversions d ’une chaîne en un type primitif String ch = " 3587 "; int n = Integer.parseInt(ch); Il existe les méthodes suivantes : Byte.parseByte, Short.parseShort, Interger.parseInt, Long.parseLong,Float.parseFloat, Double.parseDouble
Conversions entre chaînes et tableaux de caractères On peut construire une chaîne à partir d ’un tableau de caractères : char mot [] = { ‘ b ’, ‘ o ’, ‘ n ’, ‘ j ’, ‘ o ’, ‘ u ’, ‘ r ’}; String ch = new String (mot); String ch1 = new String (mot, 2, 4); ch est construite à partir du tableau mot et contient maintenant la chaîne " bonjour " ch1 est construite en prélevant 4 caractères du tableau mot, à partir de celui de rang 2; Ch1 contient la chaîne " onjo ". Transformation d ’un objet chaîne en un tableau de caractères String ch = " bonjour "; char mot []; mot = ch.toCharArray (); mot référence maintenant un tableau de 7 éléments (les 7 caractères de bonjour).
La super-classe Object (1) Toute classe dérive implicitement de la classe Object class Point { …. } class Point extends Object {… } Une variable de type Object peut donc être utilisée pour référencer un objet de type quelconque. Point p = new Point (…); Pointcol pc = new Pointcol (…); Fleur f = new Fleur (…); Object o; o = p; o = pc ; o = f;
La super-classe Object (2) Point p = new Point (…); Object o; … o = p; o.deplace (); // erreur de compilation ((Point) o).deplace();// OK en compilation (attention aux parenthèses) Point p1 = (Point) o;// OK : idem ci-dessus, avec création d’une référence p1.deplace();// intermédiaire dans p1
La méthode equals de Object (1) La méthode equals définie dans le classe Objects se contente de comparer les adresses Des deux objets concernés. Object o1 = new Point (1,2); Object o2 = new Point (1,2); o1.equals(o2) = false On peut redéfinir la méthode equals : class Point { … boolean equals (Point p) {return ((p.x==x) && (p.y==y));} }
La méthode equals de Object (2) Point a = new Point (1,2); Point b = new Point (1,2); a.equals(b) = true Point o1 = new Point (1,2); Point o2 = new Point (1,2); o1.equals(o2) = false
Les classes abstraites Une classe abstraite est une classe ayant au moins une méthode abstraite. Une méthode abstraite ne possède pas de définition. Une méthode abstraite doit obligatoirement être déclarée public. Une classe abstraite ne peut pas être instanciée ( new ). Une classe dérivée d'une classe abstraite ne redéfinissant pas toutes les méthodes abstraites est elle-même abstraite. Une classe dérivée d’une classe non abstraite peut être déclarée abstraite et/ou contenir des méthode abstraites.
Les classes abstraites Exemple (1) abstract class Shape { public abstract double perimeter(); } class Circle extends Shape {... public double perimeter() { return 2 * Math.PI * r ; } } class Rectangle extends Shape {... public double perimeter() { return 2 * (height + width); } }... Shape[] shapes = {new Circle(2), new Rectangle(2,3), new Circle(5)}; double sum_of_perimeters = 0; for(int i=0; i<shapes.length; i++) sum_of_perimeters = shapes[i].perimeter();
Les classes abstraites Exemple (2) Soit la classe : abstract class X { public abstract void f ( ); public void t ( ) { ….} … } Nous pouvons écrire une méthode d’une classe quelconque de la manière suivante : void algo (X x) { … x.f ( ); // appel correct ; accepté en compilation. On est sûr que tout objet // d’une classe dérivée de X disposera bien d’une méthode f … }
Les interfaces Une interface correspond à une classe où toutes les méthodes sont abstraites. Une classe peut implémenter ( implements ) une ou plusieurs interfaces tout en héritant ( extends ) d'une classe. Une interface peut hériter ( extends ) de plusieurs interfaces. On peut utiliser des variables de type interface. On pourra ainsi manipuler des objets de classes quelconques, non nécessairement liées par héritage, pour peu que ces classes implémentent la même interface Une interface peut aussi renfermer des constantes symboliques qui seront alors accessibles à toutes les classes implémentant l’interface.
Les interfaces Exemple abstract class Shape { public abstract double perimeter(); } interface Drawable { public void draw(); } class Circle extends Shape implements Drawable { public double perimeter() { return 2 * Math.PI * r ; } public void draw() {...} } class Rectangle extends Shape implements Drawable {... public double perimeter() { return 2 * (height + width); } public void draw() {...} }... Drawable[] drawables = {new Circle(2), new Rectangle(2,3), new Circle(5)}; for(int i=0; i<drawables.length; i++) drawables[i].draw();
Variables de type interface Bien que la vocation d’une interface soit d’être implémentée par une classe, on peut définir des variables de type interface : public interface I { …. } … I i; // i est une référence à un objet d’une classe implémentant l’interface I. Bien entendu, on ne pourra pas affecter à i une référence à quelque chose de type I Puisqu’on ne peut pas instancier une interface. En revanche, on pourra affecter à i N’importe quelle référence à un objet d’une classe implémentant l’interface I : class A implements I { … } … I i = new A ( … ) ; De plus, à travers i, on pourra manipuler des objets de classes quelconques, non Nécessairement liées par héritage, pour peu que ces classes implémentent l’inteface I.
Dérivation d’une interface interface I1 { void f (int n); static final int MAXI = 100; } interface I2 extends I1 { void g(); static final int MINI = 20; } interface I2 extends I1 { void g(); void f (int n); static final int MAXI = 100; static final int MINI = 20; } La dérivation des interfaces revient simplement à concatener des déclarations.
Conflit de noms (1) interface I1 { void f(int n); void g(); } interface I2 { void f(float x); void g(); } class A implements I1, I2 { // A doit définir deux méthodes f : void f (int) et void f(float) // mais une seule méthode g : void g () … } Il n’y a pas de conflits entre les deux interfaces I1 et I2 car elles définissent la même entête pour la méthode g.
Conflit de noms (2) interface I1 {void f (int n); void g(); } interface I2 { void f (float x); int g(); } class A implements I1, I2 { // pour satisfaire à I1 et I2, A devrait contenir à la fois une méthode void g() et // une méthode int g(), ce qui n’est pas possible d’après des règles de rédéfinition. … }
Les classes anonymes class A { public void affiche () { System.out.println (" je suis un A "); } } public class B {public static void main (String[] args) { A a; a = new A( ) { public void affiche () { System.out.println (" Je suis un anonyme derive de A "); }}; a.affiche(); }} Je suis un anonyme dérive de A Remarques : - une classe anonyme ne peut pas introduire de nouvelles méthodes. - une classe anonyme ne peut dérivée que d’une classe ou d’une interface