Programmation Java Programmation objet avec Java Concepts plus avancés Christelle Urtado & Sylvain Vauttier Janvier 2013 Redéfinition de méthode (masquage) Une sous-classe peut redéfinir le code de méthodes existant dans une de ses super-classes (directe ou indirectes), à des fins de spécialisation. On parle de redéfinition de méthode (overriding). La méthode redéfinie doit avoir exactement la même signature*. Le masquage permet de déclencher la méthode la plus spécifique. * à l exception éventuellement du type de retour qui peut être spécialisé. 1
Redéfinition de méthode : exemple public class Employe extends Personne private float salaire; public Employe (float salaireembauche) salaire = salaireembauche; public float getsalaire () return (salaire); return (salaire / 12); public class Commercial extends Employe private float chiffregenere; public Commercial (float salaireembauche) super (salaireembauche); chiffregenere = 0; public void faitaffaire (float montant) chiffregenere += montant; return (chiffregenere / 10); Redéfinition de méthode : exemple public class ProgPpal public static void main (String args []) Employe jean = new Employe (14400)); Commercial pierre = new Commercial (24000); pierre.faitaffaire (50000); System.out.println(jean.prime ()); System.out.println(pierre.prime ()); méthode prime() définie dans la classe Employe méthode prime() définie dans la classe Commercial > javac ProgPpal.java > java ProgPpal 1200 5000 > 2
Redéfinition de méthode et polymorphisme Le principe de substitution (inclusion covariante des extensions des classes) d affecter à une variable typée par une classe un objet du type d une sous-classe. On parle d affectation polymorphique. Employe jacques = new Commercial (30000); L appel d une méthode redéfinie déclenche bien la méthode la plus spécifique car la méthode à exécuter est choisie dynamiquement au runtime (et pas statiquement, à la compilation). Le choix peut ainsi être déterminé par le type réel de l objet (type dynamique) et non pas par le type déclaré pour la variable (type statique) qui est moins précis. On parle de liaison tardive (late binding). Polymorphisme et programme «générique» Le polymorphisme permet d écrire des programmes pour lesquels le même code («générique») permet de déclencher des méthodes distinctes selon le type (dynamique) de l objet (la redéfinition la plus spécifique). Ces programmes vont ainsi: s adapter finement à des types d objets distincts en déclencahnt les comportements les plus spécifiques, avoir la capacité de s adapter à des types qui ne pré-existent pas. La seule contrainte est que ceux-ci redéfinissent la(les) méthode(s) concernées. 3
Exemple de programme «générique» public class ProgPpal public static void main (String args []) Entreprise mapetiteentreprise = new Entreprise (); mapetiteentreprise.embauche (new Employe (14400)); Commercial pierre = new Commercial (24000); mapetiteentreprise.embauche (pierre); pierre.faitaffaire (50000); mapetiteentreprise.embauche (new Employe (18000)); float coutpersonnels = mapetiteentreprise.massesalariale (); public class Entreprise private Employe[] listepersonnels; private nbemployes = 0; 14400+1200 +24000+5000 +18000+1500 =64100 public Entreprise () listepersonnels = new Employe [50]; public void embauche (Employe nouveau) listepersonnels[nbemployes++] = nouveau; public float massesalariale () float cumulsalaires = 0; for (int i = 0; i < nbemployes; i++) cumulsalaires += listepersonnels [i].getsalaire () return (cumulsalaires); + listepersonnels [i].prime (); Référence à la super-classe : super Le mot réservé super permet de faire référence aux informations provenant de la super-classe directe. public class Employe extends Personne private float salaire; return (salaire * 0,1); public class Cadre extends Employe return (super.prime() / 2); 4
Programmes «génériques» : accès aux fonctionnalités spécifiques Lorsqu on utilise un type générique (une superclasse) pour typer une variable qui contient un objet spécifique (du type d une sous-classe), il n est plus possible d accéder «naturellement» aux attributs et aux méthodes spécifiques. L information de typage accessible au compilateur ne permet pas d utiliser les fonctions spécifiques. (Si on essaie, il y a une erreur de compilation). La solution : indiquer au compilateur le type réel de l objet. On parle de «forçage» de type («cast» en anglais). Forçage de type et opérateur instanceof (1) public class Employe extends Personne private float salaire; public Employe (float salaireembauche) salaire = salaireembauche; public float getsalaire () return (salaire); return (salaire / 12); public class Commercial extends Employe private float chiffregenere; public Commercial (float salaireembauche) super (salaireembauche); chiffregenere = 0; public void faitaffaire (float montant) chiffregenere += montant; return (chiffregenere / 10); 5
Forçage de type et opérateur instanceof (2) public class Entreprise private Employe[] listepersonnels; private nbemployes = 0; public Entreprise () listepersonnels = new Employe [50]; public void embauche (Employe nouveau) listepersonnels[nbemployes++] = nouveau; public float massesalariale () float cumulsalaires = 0; for (int i = 0; i < nbemployes; i++) cumulsalaires += listepersonnels [i].getsalaire () + listepersonnels [i].prime (); return (cumulsalaires); public float vente () for (int i = 0; i < nbemployes; i++) if (listepersonnels[i] instanceof Commercial) ((Commercial) listepersonnels[i]).faitaffaire (); force le compilateur à considérer que l objet est du type indiqué permet de savoir si l objet est du type souhaité Classes abstraites (1) Il peut être nécessaire au programmeur de créer une classe déclarant une méthode sans la définir (c-à-d sans en donner le code). La définition du code est dans ce cas laissée aux sous-classes. Une telle classe est appelée classe abstraite. Elle doit être marquée avec le mot réservé abstract. Toutes les méthodes de cette classe qui ne sont pas définies doivent elles-aussi être marquées par le mot réservé abstract. 6
Classes abstraites (2) Une classe abstraite ne peut pas être instanciée. Par contre, il est possible de déclarer et d'utiliser des variables du type de la classe abstraite. Si une sous-classe d'une classe abstraite ne définit pas toutes les méthodes abstraites de ses superclasses, elle est abstraite elle aussi. public abstract class Polygone private int nombrecotes = 3; public abstract void dessine (); // methode non définie public int getnombrecotes() return(nombrecotes); Interfaces Si le programmeur veut s'assurer qu'une certaine catégorie de classes (pas forcément liées par des relations d héritage) implémente un ensemble de méthodes, il peut regrouper les déclarations de ces méthodes dans une interface. De telles classes pourront ainsi être manipulées de manière identique. Les classes désirant appartenir au type d objets ainsi défini : déclarent qu'elles implémentent cette interface, fournissent le code des méthodes déclarées dans cette interface. Mots réservés : interface, implements. 7
Interfaces : Exemple (1) public interface Conduisible void demarrermoteur (); void coupermoteur (); void tourner (float angle); public class TondeuseGazon implements Conduisible //... public void demarrermoteur ()... public void coupermoteur ()... public void tourner (float angle)... public class Voiture implements Conduisible //... public void demarrermoteur ()... public void coupermoteur ()... public void tourner (float angle)... Interfaces : Exemple (2) public class ProgPpal public static void main (String [] args) Voiture mavoiture = new Voiture(); TondeuseGazon matondeuse = new TondeuseGazon(); Conduisible vehicule; Boolean weekend; //... if(weekend == true) vehicule=matondeuse; else vehicule=mavoiture; vehicule.demarrermoteur(); vehicule.tourner(90); vehicule.coupermoteur(); code générique 8
Interfaces (suite) Toutes les méthodes d'une interface sont abstraites. Le modificateur abstract est facultatif. Les interfaces permettent à une classe d objets d appartenir à plusieurs types, malgré un héritage simple entre classes. public class Tapis... public class TapisVolant extends Tapis implements Conduisible... Les interfaces peuvent hériter d une ou plusieurs autres interfaces. 9