Powerpoint

publicité
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:
 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
2
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 sousclasse (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
3
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.
4
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
Vehicle
Car
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
5
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++)
6
Diagramme UML
montrant l`héritage
Words
+ main (args : String[]) : void
Book
Dictionary
- definition: int
+ definitionMessage( ): void
# pages: int
+ pageMessage( ):void
7
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();
}
}
8
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();
}
}
9
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: 1000
Number of definitions: 52500
Definitions per page: 52
10
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
11
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.
12
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
13
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: 1500
Number of definitions: 52500
Definitions per page: 35
14
La classe parent:
Book2.java
public class Book2
{
protected int pages;
public Book2(int numPages)
{
pages = numPages;
}
// print a message
public void pageMessage()
{
System.out.println("Number of pages: " + pages);
}
}
15
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);
}
16
}
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
17
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é
18
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
19
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 fine
Warning: Time is shrinking
20
Thought.java
public class Thought
{
public void message()
{
System.out.println("I feel fine");
System.out.println();
}
}
21
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();
22
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é
23
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.
24
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
Business
RetailBusiness
KMart
Macys
ServiceBusiness
Kinkos
25
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
26
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
27
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
28
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.
29
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
30
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
Christmas
Holiday day;
day = new Christmas();
31
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»)
32
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)
33
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
34
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);
}
35
Pizza.java
public class Pizza extends FoodItem
{
public Pizza(int fatGrams)
{
super(fatGrams, 8);
}
}
36
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;
37
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
38
Polymorphisme via héritage

Considérons la hiérarchie de classe suivante:
StaffMember
Volunteer
Employee
Executive
Hourly
• Considérons maintenant la tâche de payer tous les employés
39
Firm.java
public class Firm
{
public static void main (String[] args)
{
Staff personnel = new Staff();
personnel.payday();
}
}
Name: Sam
Phone: 555-3456
Paid: 3341.07
Name: Joe
Phone: 555-1432
Paid: 1000.0
Name: Sue
Phone: 555-6567
Thanks!
Name: Ann
Phone: 555-7876
40
Staff.java
public class Staff
{
private StaffMember[] staffList;
public Staff()
{
staffList = new StaffMember[4];
}
staffList[0]
staffList[1]
staffList[2]
staffList[3]
=
=
=
=
new
new
new
new
Executive("Sam", "555-3456", 2341.07);
Employee("Joe", "555-1432", 1000.00);
Volunteer("Sue", "555-6567");
Volunteer("Ann", "555-7876");
Continued…
41
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);
}
42
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();
}
43
Volunteer.java
public class Volunteer extends StaffMember
{
public Volunteer (String eName, String ePhone)
{
super(eName, ePhone);
}
}
public double pay()
{
return 0.0;
}
44
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;
45
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;
46
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
47
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é
48
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
49
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
50
Sommaire:
Chapitre 7

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
51
Téléchargement