510 likes | 628 Views
CSI1502 Principes fondamentaux en conception des logiciels. Chapitre 7: L‘héritage. Objectifs du cours: L‘héritage. Une autre technique OO fondamentale dénommé l`héritage, pour organiser et créer des classes et promouvoir leur réutilisation. Comprendre ce qui suit:
E N D
CSI1502Principes fondamentaux en conception des logiciels Chapitre 7: L‘héritage
Objectifs du cours:L‘héritage • Une autre technique OO fondamentale dénommé l`héritage, pour organiser et créer des classes et promouvoir leur réutilisation. • Comprendre ce qui suit: • Dériver de nouvelles classes de classes existantes • Créer des hiérarchies de classe: une classe parent et de classes enfants • Le modificateur d`accès protected • Le Polymorphisme via l`héritage • Hiérarchies héréditaires pour les interface
Qu`est-ce qu`est l`héritage? • L`héritage permet au programmeur de dériver de nouvelles classes à partir de classe existante. • La classe existante est dénommé la classe parent, ou super classe (superclass) ou classe de base (base class). • La classe dérivé est dénommé classe enfant ou sous-classe (subclass) • Comme le nom indique, l`enfant hérite des caractéristiques de la classe parent. • C`est à dire que la classe enfant hérite: • Des méthodes et données définis dans la classe parent
L`héritage : Idée principale • Afin d`ajuster la classe dérivée un programmeur peut: • Ajouter de nouvelles variables ou méthodes, ou • Modifier les éléments hérités • La réutilisant de logiciel est au coeur de l`héritage • En utilisant des objets logiciels existants afin de créer d`autres objets logiciels, nous bénéficions de tout le travail qui à été mis dans la création, implémentation et vérification des logiciels existants.
Vehicle Car Visualisation de l`héritage • Les relations héritage sont souvent montrées de façon graphiques dans les diagramme de classe, avec une flèche allant vers la classe parent L`héritage crée une relation «est un(e)» (is-a), soit que l`enfant est une version plus spécifique que le parent
Dérivation de sous classes • En Java, le mot réservé extends est utilisé pour établir une relation d`héritage class Car extends Vehicle { // class contents } • Voir Words.java, Book.java et Dictionary.java (pp.384++)
Diagramme UML montrant l`héritage Words Dictionary - definition: int + main (args : String[]) : void + definitionMessage( ): void Book # pages: int + pageMessage( ):void
Programme pilote:Words.java public class Words{ //Instansiates a derived class public static void main (String[] args) { Dictionary webster= new Dictionary(); webster.pageMessage(); webster.definitionMessage(); }}
Book.java:La Classe Parent public class Words{ //Instansiates a derived class public static void main (String[] args) { Dictionary webster= new Dictionary(); webster.pageMessage(); webster.definitionMessage(); }}
Dictionary.java:La classe enfant public class Dictionary extends Book{ private int definitions = 52500; public void definitionMessage() { System.out.println("Number of definitions: " + definitions); System.out.println("Definitions per page: " + definitions/pages); }} Number of pages: 1000Number of definitions: 52500Definitions per page: 52
Modificateur d`accès:Le modificateur protected • Les modificateurs d`accès déterminent quels membres de la classe sont héritable et lesquels ne le sont pas • Les variables et méthodes déclarées avec un modificateur public sont héritées; ceux avec un modificateur private ne le sont pas • Mais le variables public violent le principe d`encapsulation • Il existe un troisième modificateur d`accès qui aide les situation d`héritage: protected
Le modificateur protected • Le modificateur d`accès protected permet à un membre de la classe parent a être hérité par l`enfant • Le modificateur protected donne une meilleure encapsulation que le modificateur public. • Malgré ça, le modificateur protected n`a pas une encapsulation plus forte que le modificateur private • Plus de détails sure chaque modificateur est donné dans l`appendice F.
Référence à un parent:La référence super • Les constructeurs ne sont pas héritables, malgré leur modificateur public • Et pourtant souvent nous voudrions utiliser le constructeur de la classe parent afin d`initialiser la «partie du parent» dans l`objet • La référence super peut-être utilisée pour invoquer la classe parent, et souvent est utilisé pour invoquer le constructeur de celui-ci • Voir l`exemple Word2, pp.388-393
Le programme pilote:Words2.java public class Words2{ //Instansiates a derived class public static void main (String[] args) { Dictionary2 webster= new Dictionary2(1500, 52500); webster.pageMessage(); webster.definitionMessage(); }} Number of pages: 1500Number of definitions: 52500Definitions per page: 35
La classe parent:Book2.java public class Book2 {protected int pages;public Book2(int numPages){ pages = numPages;}// print a messagepublic void pageMessage(){ System.out.println("Number of pages: " + pages);} }
La classe enfant:Dictionary2.java public class Dictionary2 extends Book2 { private int definitions; public Dictionary2(int numPages, int numDefinitions) {super(numPages);definitions = numDefinitions; } public void definitionMessage() {System.out.println("Number of definitions: " + definitions);System.out.println("Definitions per page:“ + definitions/pages); } }
Plus au sujet de la référence super • Un constructeur d`une classe enfant et responsable d`appeler le constructeur du parent • La première ligne du constructeur doit utiliser la référence super afin d`appeler le constructeur du parent • La référence super peut aussi être utilisé afin d`accéder à d`autres variables et méthodes définies dans la classe parent
L`héritage simple vs. l`héritage multiple • Java ne supporte que l`héritage simple, soit qu`une classe dérivé ne peut n`avoir qu`un seul parent! • Certains autre langages supportent l`héritage multiple, ce qui permet à certaines classes d`être dérivées de plusieurs classe bénéficiant de toutes les variables et méthodes de ses parent • Ceci implique que les collisions, tel que d`avoir deux variables du même nom doivent alors être résolues • Dans la plus part des cas, l`utilisation d`interface nous donne les avantages de l`héritage multiple sans la complexité
L`outrepassement de méthodes • Une classe enfant peut outrepasser la définition d`une méthode hérité en faveur de sa propre méthode • C`est à dire, que un enfant peut redéfinir une méthode héritée de son parent • La nouvelle méthode doit avoir la même signature que la méthode du parent, mais peut avoir un fonctionnalité différente. • Le type de l`objet en train d`exécuter détermine quel version de la méthode qui doit être invoquée
L`outrepassement de méthodes :Messages.java (p.392) public class Messages{ public static void main (String[] args) { Thought parked = new Thought(); Advice dates = new Advice(); parked.message(); dates.message(); }} I feel fineWarning: Time is shrinking
Thought.java public class Thought{ public void message() { System.out.println("I feel fine"); System.out.println(); }}
Advice.java public class Advice {public void message(){ System.out.println("Warning: Time is shrinking"); System.out.println();} } public class Advice extends Thought{ public void message() { System.out.println("Warning: Time is shrinking"); System.out.println();super.message(); }}
L`outrepassement de méthodes et de variables • Notez que la méthode parent peut être invoqué spécifiquement en utilisant la référence super • Si une méthode est déclaré avec le modificateur final, on ne peut l`outrepasser • Le concept d`outrepassement peut aussi être appliqué au variables (dénommé shadowing variables en anglais). Mais ceci, de règle générale, est non recommandé
La surcharge de méthodes vs. l`outrepassement de méthodes • La surcharge de méthodes concerne plusieurs méthodes dans une même classe ayant le même nom mais pas la même signature. • L`outrepassement de méthodes concerne deux méthodes l`une dans une classe parent l`autre dans la classe enfant ayant le même nom et la même signature. • La surcharge de méthodes vous permet de définir des opérations similaires de façon différentes pour différentiels type de données • L`outrepassement de méthodes vous permet de définir une opération similaire de façon différente pour des objets différents.
Business RetailBusiness ServiceBusiness KMart Macys Kinkos Hiérarchies de classe • Une classe enfant d`un parent peut-être le parent d`une autre classe enfant, créant ainsi une Hiérarchies de classe
Hiérarchies de classe: Quelques définitions • Deux enfants du même parents sont dénommé «siblings» • Un bon concept est de mettre les aspects commun aussi haut que raisonnable dans une hiérarchie • Un membre héritable se fait passer dans tous les enfants • Le mécanisme d`héritage est transitif • C`est à dire que une classe enfant hérite de tous ces ancêtres • Il n`existe pas «La» hiérarchie de classe qui est appropriée dans toutes les situations • Les hiérarchies de classes doivent souvent être modifiées et améliorées afin de rester utile
La classe Object:Incluse dans java.lang • Toutes les classes sont dérivées de la classe Object • La classe Object est l`ultime parent de toute les hiérarchies de classe • La classe Object contient quelques méthodes utiles qui sont hérité par toutes les classes • Par exemple, la méthode toString est définie dans la classe Object • C`est pourquoi la méthode println peut appeler toString pour tous les objets qui lui est passé – tous les objets sont garantis d`avoir une méthode toString par l`héritage
Classes Abstraites • Une classe abstraite est une classe qui représente un concept générique dans une hiérarchie • Une classe abstraite ne peut-être utilisé • Nous utilisons le modificateur abstract sur la l`entête de la classe pour déclarer une classe abstraite abstract public class vehicle
Que sont les Classes Abstraites? • Une classe abstraite contient souvent des méthodes sans définitions (comme les interfaces), mais ce n`est pas obligatoire • Contrairement à une interface, le modificateur abstract peut-être appliqué à chaque méthode abstraite • Une classe abstraite contient typiquement des méthodes non abstraites avec des méthodes fonctionnelles, faisant la différence entre les classes abstraites et les interfaces • Une classe déclaré abstraite ne doit pas nécessairement contenir des méthodes abstraites.
Que sont les Classes Abstraites? • L`enfant d`une classe abstraite doit outrepasser les méthodes abstraites du parent, sinon l`enfant va aussi devenir avstrait • Une méthode abstraite ne peut être définie comme • final (car la méthode doit être outrepassée) • static (car la méthode n`est pas définie) • L`utilisation d`une classe abstraite est une décision de concept; cela permet de créer des éléments communs dans une classe trop générale pour être utile. Par exemple • Vehicle, FuelConsumption • Employee, BenefitsCalculation
Holiday Christmas Utilisation indirecte de membres d`une classe:Références et héritage • Un objet référé peut faire référence à un objet de sa classe, ou à un objet de n`importe quel autre classe relié par héritage • Par exemple, si la classe Holiday est utilisé pour dériver un enfant dénommé Christmas, alors une référence Holiday peut-être utilisé pour pointer sur un objet Christmas Holiday day; day = new Christmas();
Références et héritage :Ouverture vs fermeture • Conversion d`ouverture («Widening conversion»): • Assigner un objet prédécesseur à une référence d`ancêtre • Fait par une simple assignation • Conversion de fermeture («Narrowing conversion»): • Assigner un objet d`ancêtre prédécesseur à une référence de prédécesseur • Fait par un conversion («cast»)
Utilisation indirecte de membres non hérités • Un membre hérité peut être référencé directement par nom dans la classe enfant, tout comme si il y fût déclaré • Mais, même si une méthode ou variable n`est pas hérité par l`enfant, on peut encore y accéder au travers des méthodes du parent • Voir FoodAnalysis.java(page 403) • Voir FoodItem.java(page 404) • Voir Pizza.java(page 405)
FoodAnalysis.java public class FoodAnalysis { public static void main (String[] args) { Pizza special = new Pizza(275); System.out.println("Calories per serving: " + special.caloriesPerServing()); }} Calories per serving: 309
FoodItem.java public class FoodItem{ final private int CAL_PER_GRAM = 9; private int fatGrams; protected int servings; public FoodItem(int numFatGrams, int numServings) { fatGrams = numFatGrams; servings = numServings; } private int calories() { return fatGrams*CAL_PER_GRAM; } public int caloriesPerServing() { return (calories()/servings); }}
Pizza.java public class Pizza extends FoodItem{ public Pizza(int fatGrams) { super(fatGrams, 8); }}
Polymorphisme: Avoir plusieurs formes • Une référence peut être polymorphique, ce qui peut être défini comme «avoir plusieurs formes» • Une variable référencé polymorphique peut référer à différent types d`objets durant l`exécution • Les références polymorphiques sont résolues durant l`exécution; ceci est dénommé «dynamic binding» • L`utilisation prudente de références polymorphiques permet de construire des logiciels élégant et robustes. Mammal pet; Horse myhorse = new Horse(); // Horse derived from Mammal // Horse is-a Mammal pet = myhorse;
Polymorphisme via héritage • Supposons que la classe Holiday à une méthode dénommé celebrate, et que la classe Christmas l`outrepasse • Considérons maintenant l`invocation suivante: day.celebrate(); • Si day référe à un objet Holiday, il invoce la version celebrate de Holiday; de même pour l`objet Christmas
StaffMember Volunteer Employee Executive Hourly Polymorphisme via héritage • Considérons la hiérarchie de classe suivante: • Considérons maintenant la tâche de payer tous les employés
Firm.java public class Firm{ public static void main (String[] args) { Staff personnel = new Staff(); personnel.payday(); }} Name: SamPhone: 555-3456Paid: 3341.07Name: JoePhone: 555-1432Paid: 1000.0Name: SuePhone: 555-6567Thanks!Name: AnnPhone: 555-7876
Staff.java public class Staff{ private StaffMember[] staffList; public Staff() { staffList = new StaffMember[4]; staffList[0] = new Executive("Sam", "555-3456", 2341.07); staffList[1] = new Employee("Joe", "555-1432", 1000.00); staffList[2] = new Volunteer("Sue", "555-6567"); staffList[3] = new Volunteer("Ann", "555-7876"); } Continued…
Staff.java (cont.) … public void payday() { double amount; for (int count = 0; count < staffList.length; count++) { System.out.println(staffList[count]); amount = staffList[count].pay(); if (amount == 0) System.out.println("Thanks!"); else System.out.println("Paid: " + amount); } }}
StaffMember.java abstract public class StaffMember{ protected String name; protected String phone; public StaffMember(String eName, String ePhone) { name = eName; phone = ePhone; } public String toString() { String result = "Name: " + name + "\n"; result += "Phone: " + phone; return result; } public abstract double pay();}
Volunteer.java public class Volunteer extends StaffMember{ public Volunteer (String eName, String ePhone) { super(eName, ePhone); } public double pay() { return 0.0; }}
Employee.java public class Employee extends StaffMember{ protected double payRate; public Employee(String eName, String ePhone, double rate) { super(eName, ePhone); payRate = rate; } public double pay() { return payRate; } public String toString() { String result = super.toString(); return result; } }
Executive.java public class Executive extends Employee{ private double bonus; public Executive(String eName, String ePhone, double rate) { super(eName, ePhone, rate); bonus = 1000; } public double pay() { double payment = super.pay() + bonus; return payment; }}
Hiérarchies d`interface • L`héritage peut-être appliqué aux interfaces aussi bien qu`aux classes • Une interface peut-être dérivé d`une autre interface • L`interface enfant hérite toutes les méthodes abstraites du parent • Une classe implémentant l`interface enfant doit définir toutes les méthodes de l`interface du parent ainsi que ceux de l`enfants • Tous les membres d`une interface sont public • Notez que les hiérarchies de classes et hiérarchies d`interface sont distinctes
Polymorphisme via Interfaces • Un nom d`interface peut-être utilisé pour déclarer une variable d`objet référence • Les interfaces permettent des références polymorphiques dans lesquelles • la méthode qui se fait invoquer est determiné par l`objet référencé
Speakers, Philosophers and Dogs public interface Speaker { public void speak(); public void announce (String str); } Assumons les classes Philosopher et Dog sont implementé en utilisant l`interface Speaker: Speaker guest; guest = new Philosopher(); guest.speak(); speak method dans la classe Philosopher guest = new Dog(); guest.speak; speak method dans la classe Dog
Héritage et GUIs:Plus à ce sujet dans le Chapitre 9 • Un applet est un excellent exemple d`héritage • Rappelons nous que lors de la définition d`un applet, on étend la classe Applet ou la classe JApplet • Les classes Applet et JApplet s`occupent de tous les détails pour la création et l`exécution d`un applet, incluant les interactions avec le fureteur • Quand nous définissons certaines méthodes, tel que paint d`un applet, en effet nous outrepassons la méthode définie dans la classe Component, qui est ultimement hérité dans les Applet ou JApplet