L’héritage (1) L’héritage (2) ♦ Une classe ne peut hériter (extends) que d'une seule classe (héritage simple). ♦ Toute classe dérive, par défaut, de java.lang.Object ♦ Une référence d'une classe C peut contenir des instances de C ou des classes dérivées de C. ♦ L'opérateur instanceof permet de déterminer la classe d'une instance. ♦ Les classes final ne peuvent pas être redéfinies dans des sous-classes (ne peut pas être héritée). ♦ Les méthodes final ne peuvent pas être redéfinies. Le langage Java B. Djafri (46) public class Ellipse { public double r1, r2; public Ellipse(double r1, double r2) { this.r1 = r1; this.r2 = r2; } public double area(){...} } final class Circle extends Ellipse { public Circle(double r) {super(r, r);} public double getRadius() {return r1;} } { Ellipse e = new Ellipse(2.0, 4.0); Circle c = new Circle(2.0); System.out.println("Aire de e:" + e.area() + ", Aire de c:" + c.area()); System.out.println((e instanceof Circle)); // false System.out.println((e instanceof Ellipse)); // true System.out.println((c instanceof Circle)); // true System.out.println((c instanceof Ellipse)); // true (car Circle dérive de Ellispe) e = c; System.out.println((e instanceof Circle)); // true System.out.println((e instanceof Ellipse)); // true double r = e.getRadius(); // Error: method getRadius not found in class Ellipse. c = e; // Error: Incompatible type for =. Explicit cast needed. Le langage Java Le masquage des variables (1) Le masquage des variables (2) class A { int x; void m() {...} } ♦ Une classe peut définir des variables portant le même nom que celles de ses classes ancêtres (super classes). class B extends A{ float x; void m() {...} } ♦ Une classe peut accéder aux attributs redéfinis de sa classe mère en utilisant super ou par cast. ♦ Une classe peut accéder aux méthodes redéfinies de sa classe mère en utilisant super. ♦ Les constructeurs ne sont pas hérités (≠ méthodes) Le langage Java B. Djafri (47) B. Djafri (48) class C extends B { double x, a; void m() {...} void test() { a = super.x; a = super.super.x; a = ((B)this).x; a = ((A)this).x; super.m(); super.super.m(); ((B)this).m(); } } Le langage Java // // // // // // // a reçoit la valeur de Syntax error a reçoit la valeur de a reçoit la valeur de Appel de la méthode m Syntax error Appel de la méthode m la variable x de la classe B la variable x de la classe B la variable x de la classe A de la classe B de la classe C (et non B) B. Djafri (49) Structure des classes (suite) L’encapsulation class c1 { public int A; protected int B; int C; private int D; Package P1 Package P2 class c4 extends c1 { ... } } ♦ Le mot clé class peut-être précédé de l'un des trois mots clé : public, abstract et final • public : la classe peut-être utilisée par n'importe quelle class c2 extends c1 { ... } class c3 { ... } Accessible par c2 Accessible par c3 Accessible par c4 Accessible par c5 autre classe. class c5 { ... } A o o o o B o o o - C o o - • final : aucune classe ne peut hériter d'elle. • abstract : la classe ne peut pas être instanciée. D - Le langage Java • Par défaut, une classe ne peut-être utilisée que par les classes appartenant au même package. B. Djafri (50) Le langage Java Copies d’objets (1) ♦ ♦ ♦ ♦ B. Djafri (51) Copies d’objets (2) La copie des objets ≠ copies des références Utilisation de la méthode particulière clone() La méthode clone() est héritée de java.lang.Object Le transtypage est nécessaire pour l’utilisation de la méthode Point p1 = new Point(3.5, 7.1); Point p2 = p1; // référence le même objet Point p3 = (Point)p1.clone(); // Attention ! p3.x = 11.5; clone() int[] T = {1, 2, 3}; int[] copy = (int[])T.clone(); // une copie du tableau (retourne un Object) ♦ Tous les objets ne peuvent êtres clonés (implémentation de l’interface Cloneable) ♦ clone() crée un copie superficielle (les références membres sont copiées et non clonées) ♦ La méthode clone() peut être redéfinie Le langage Java B. Djafri (52) Point[][] tPoints = { {new Point()}, {new Point(), new Point(3., 5.)} }; Point[][] copy = (Point[][]) tPoints.clone(); // copie les deux références uniquement Le langage Java B. Djafri (53) Comparaison d’objets (1) Comparaison d’objets (2) ♦ L’opérateur de comparaison (==) compare des références et des valeurs primitives. ♦ Deux types d’égalité • Égalité de références • Égalité des objets (objets équivalents, même contenu) ♦ La méthode equals() teste l’équivalence de deux objets ♦ Tous les objets héritent la méthode equals() ♦ L’implémentation par défaut est : == Le langage Java String message = "Hello!" ; String s = "Hello!" ; if(message == s) ... // les 2 références sont différentes int[] T = {1, 2, 3}; int[] A = (int[])T.clone(); if(T == A) ... // même contenu, mais pas égaux (équivalents) if(message.equals(s))... // il y a égalité B. Djafri (54) Le langage Java Conversion de type B. Djafri (55) Destruction d’objets (1) ♦ Java n’autorise aucune conversion entre types primitifs et types références ♦ Java autorise certaines conversions entre certains types références • Types appartenant à la même hiérarchie (hiérarchie de classes) • int, double, … en String : la méthode toString() héritée de java.lang.Object ♦ La destruction des objets est prise en charge par le Garbage Collector (GC). ♦ Le GC détruit les objets pour lesquels il n'existe plus de référence. ♦ Les destructions sont asynchrones (le GC est géré dans un thread (processus léger de basse priorité). ♦ Aucune garantie n'est apportée quant à la destruction d'un objet. ♦ La méthode finalize()est appelée lorsque l'objet est détruit. ♦ Chaque classe possède une méthode finalize(), qui peut être redéfinie. ♦ Les tableaux n’ont pas de hiérarchie de types (classes) Le langage Java B. Djafri (56) Le langage Java B. Djafri (57) Destruction d’objets (2) Les classes abstraites (1) ♦ Une méthode abstraite ne possède pas de définition (corps). public class Point { ... protected void finalize(){ ♦ Une classe contenant une méthode abstraite est une classe abstraite et doit être déclarée abstraite (abstract). System.out.println("destruction de l’objet"+ this); } } ♦ Une classe abstraite est précédée du mot clé abstract {... Point p1; if (condition) { Point p2 = new Point(); // p2 référence une nouvelle instance de Point p1 = p2; // p1 et p2 référencent la même instance de la classe Point } // La référence p2 n'est plus valide, mais il reste une référence p1 // sur l'instance p1=null; // L'instance ne possède plus de référence. Elle n'est plus // accessible. A tout moment, le GC peut détruire l'objet. ♦ Une classe abstraite ne peut pas être instanciée (new), mais peut être héritée (sous-classe concrète). Le langage Java B. Djafri (58) ♦ Une classe abstraite peut définir des méthodes abstraites (non static, private, final). ♦ Une classe dérivée d'une classe abstraite ne redéfinissant pas toutes les méthodes abstraites est elle-même abstraite. Le langage Java Les classes abstraites (2) Les classes abstraites (3) public abstract class Shape { public abstract double perimeter(); } public abstract class Message { private String sender; public Message(String from){ sender = from; } public abstract void play(); public String getSender(){ return sender; } } public class Circle extends Shape { ... public double perimeter() { return 2 * Math.PI * r ; } } public class Rectangle extends Shape { ... public double perimeter() { return 2 * (height + width); } } public class TextMessage extends Message { private String text; public TextMessage(String from, String t){ super(from); text = t; } public void play(){ System.out.println(text); } } ... 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(); Le langage Java B. Djafri (59) public class VoiceMessage extends Message { ... } B. Djafri (60) Le langage Java B. Djafri (61) Les interfaces (2) Les interfaces (1) abstract class Shape { public abstract double perimeter(); } ♦ Une interface correspond à une classe abstraite où toutes les méthodes sont abstraites (interface = type référence) • Les méthodes sont déclarées implicitement abstraites et publiques (même si les mots clés public et abstract sont omis). • Que des méthodes d’instance ou des constantes (pas de constructeurs, de variables d’instance, de méthodes statiques). • Pas de détail, pas d’attributs (sauf des constantes static final) ♦ Une classe peut implémenter (implements) une ou plusieurs interfaces tout en héritant (extends) d'une classe (une seule). ♦ Une interface peut hériter (extends) de plusieurs interfaces. Le langage Java B. Djafri (62) 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, Serializable { ... 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(); Le langage Java B. Djafri (63)