L'avantage de la programmation orientée objet repose sur la
protection d'accès et de lecture des données manipulées
(Encapsulation), la factorisation et la portabilité du code (L'héritage) et
la capacité de pouvoir définir des comportements spécifiques à un type
d'objet sans impacter sa hiérarchie (Polymorphisme)
I. En quoi consiste l’encapsulation ?
L’encapsulation consiste à définir la visibilité et l’accessibilité des propriétés et
méthodes d’une classe pour mieux en maîtriser leur utilisation. Pour cela, il suffit de
déclarer « private » les données à encapsuler et de définir des méthodes permettant
de les lire et de les modifier : on appelle ces méthodes « getter » (pour la lecture) et
« setter » (pour la modification).
Getter : méthode « public » permettant de définir la manière de lecture d’un attribut
privé. Son type de retour est celui de la donnée retournée et son nom est souvent
composé de « get » et du nom de l’attribut qu’elle retourne.
Setter : méthode « public » permettant de définir la manière de modification d’une
donnée. Souvent, elle ne retourne rien (« void ») et prend un paramètre du même de
type que la donnée à modifier. Son nom se compose de la mention « set » et du nom
de l’attribut concerné.
package invivoo;
public class Car {
// Declaring attributes
private String brand ;
private String registration ;
private int x ;
private int y ;
/**
* Default constructor to initialize coords.
*/
public Car(){
x=0 ;
y=0 ;
}
/**
* Another constructor to set the brand and the id number.
*
* @param brand : car brand
* @param registration : registration number
*/
public Car(String brand, String registration){
this() ; // call the first constructor (not mandatory)
[Link](brand); // this : to differentiate the given parameter and the instance attribute.
[Link](registration);
}
/**
* A simple way to run the car
*/
public void move(){
x++ ;
y++ ;
}
// return the brand
public String getBrand() {
return brand;
}
// set the brand
public void setBrand(String brand) {
[Link] = brand;
}
// return the registration number
public String getRegistration() {
return registration;
}
// define (set) the registration number
public void setRegistration(String registration) {
[Link] = registration;
}
}
package invivoo;
public class Main {
public static void main(String[] args) {
Car niceCar = new Car("Mercedes", "AB123YZ") ;
// getting the brand by the getter (getBrand)
[Link]("Brand: " + [Link]());
// getting the registration number by the getter (getRegistration)
[Link]("Registration: " + [Link]());
// modifying the registration number
[Link]("AA000ZZ");
// Printing again the registration number to check modification
[Link]("New Registration: " + [Link]());
}
}
OUTPUT :
Brand: Mercedes
Registration: AB123YZ
New Registration: AA000ZZ
II. Que signifie l’héritage en POO et quelle est son
utilité ?
En résumé, l’héritage consiste à définir une classe par extension des mécanismes
et attributs d’une autre classe. En outre, pour un ensemble d’entités du monde réel
donné, cela consiste à regrouper leurs caractéristiques communes dans une classe
mère de laquelle seront dérivées les classes (filles) correspondant à ces entités.
A retenir :
•En Java, il est impossible d’hériter de deux ou plusieurs classes. Si un tel besoin
se présente, on pourrait se servir des « interfaces ».
•L’héritage se fait grâce au mot-clé « extends »,
•L’appel d’un constructeur de la classe mère depuis une classe fille se fait avec le
mot-clé « super ».
•L’héritage permet d’éviter de répéter un code plusieurs fois et de ne pas modifier
un code déjà existant dans une classe de base :
•Exemple : Class Point à Namedpoint : un point nommé en plus de ses coordonnées
et mécanismes intégrés.
•Il existe en Java des classes non héritables, par exemple, la classe « String ».
III. Qu’est-ce que la « surcharge » en POO ?
En programmation orientée objet, la surcharge, aussi appelée
« overloading », consiste à déclarer, dans une même classe, deux méthodes de
même nom mais avec des sémantiques différentes :
•Même nom de méthode,
•Paramètres différents (soit sur le nombre ou le/les type(s)),
•Le type de retour n’est pas pris en compte.
public class Car {
private String brand;
private String registration;
private int x;
private int y;
// A way to create a car
public car () {
brand = BrandType._DEFAULT_BRAND;
}
// Another one to create a car by providing parameters
public Car (String brand, String registration) {
[Link] = brand;
[Link] = registration;
}
}
Figure 3 – Illustration de la Surcharge du constructeur
L’aspect de la « surcharge » est retrouvé lors de la déclaration de plusieurs
constructeurs dans une même classe.
Supposons maintenant que la classe « Car » dispose d’une méthode move avec un
comportement standard de déplacement.
On pourrait alors définir une autre méthode de déplacement un peu plus
sophistiquée en précisant l’accélération et un angle de rotation (si l’angle est nul on
avance tout droit…). Notamment, en surchargeant la méthode move déjà existante.
// Following the diagonal
public void move () {
x++;
y++;
}
public void move (double speed, double rotation) {
// calculate new position with speed and rotation...
}
Figure 5 – Illustration de la surcharge de méthode
IV. Qu’est-ce que la « redéfinition » en POO ?
La redéfinition, aussi appelée « overriding », consiste à définir le comportement
d’une méthode selon le type de l’objet qui l’invoque, i.e., elle consiste à donner une
nouvelle implémentation à une méthode héritée sans changer sa signature :
•Le même nom de méthode
•Même type de retour
•Même paramètre (nombre et type)
public class Vehicule {
public Vehicule () {
}
public void describe () {
[Link]("Un véhicule");
}
}
public class Scoot extends Vehicule {
public Scoot(){
}
@Override
public void describe() {
[Link]("Excatement un Scoot.");
}
}
Figure 7 – Illustration de la redéfinition par l’héritage
Remarques :
Les méthodes (abstraites et par défaut) définies dans une interface sont aussi
considérées comme des méthodes d’instance.
public interface Mobile {
public void move() ;
}
public class Train implements Mobile {
@Override
public void move() {
[Link]("Train : Sur les rails.");
}
}
public class Avion implements Mobile {
@Override
public void move() {
[Link]("Avion : Par l'air");
}
}
import [Link];
import [Link];
public class Main {
public static void main(String[] args) {
List<Mobile> mobiles = new ArrayList<>() ;
[Link](new Avion()) ;
[Link](new Train()) ;
for(Mobile m : mobiles)
[Link]();
}
}
Output :
Avion : Par l'air
Train : Sur les rails.
Figure 8 – Illustration de la redéfinition en suivant un contrat
NB : une méthode redéfinie peut bel et bien être surchargée
Maintenant, vous savez donc comment répondre aux questions sur ces quatre
grands principes de la POO et expliciter leur mise en œuvre en Java. Le prochain
article sera un focus sur les modificateurs d’accès du langage Java qui vont nous
permettre de mettre en pratique le principe de l’encapsulation.
Vous pouvez également retrouver mon premier article où j’explique le concept de
POO en Java.
Comment fonctionne la POO ?
La POO repose sur 4 principes :
•L'encapsulation
•L'abstraction
•L'héritage
•Le polymorphisme
Le principe d'encapsulation
L'encapsulation présente toutes les informations importantes d'un objet à
l'intérieur de l'objet et n'expose que les informations choisies au monde
extérieur.
Cette propriété garantit que les informations d'un objet sont cachées au monde
extérieur en regroupant dans une classe les caractéristiques ou attributs qui ont
un accès privé, et les comportements ou méthodes qui ont un accès public.
L'encapsulation de chaque objet est responsable à la fois de ses informations et
de son état. Celui-ci ne peut être modifié que par les méthodes propres à l'objet.
De cette façon, les attributs internes d'un objet sont inaccessibles de l'extérieur
et ne peuvent être modifiés qu'en appelant les fonctions correspondantes. Cette
encapsulation prévient ainsi toute utilisation inappropriée ou inattendue de
l'objet.
Exemple d'encapsulation avec une voiture. La voiture partage des informations
publiques par le biais des feux de freinage ou des clignotants pour indiquer les
virages ou les potentiels dangers, c'est l'interface publique. En revanche,
l'interface interne, le mécanisme de conduite de la voiture, est cachée sous le
capot. Lors de la conduite d'une voiture, il est nécessaire d'indiquer les
mouvements aux autres conducteurs, mais pas d'exposer des données privées
sur le type de carburant ou la température du moteur, car cela représente
beaucoup de données, ce qui perturberait les autres conducteurs.
Le principe d'abstraction
Un autre principe de la programmation orientée objet est l'abstraction, qui se
produit lorsque l'utilisateur interagit uniquement avec des attributs et des
méthodes sélectionnés d'un objet, en utilisant des outils de haut niveau
simplifiés pour accéder à un objet complexe.
Dans la POO, les programmes sont généralement très volumineux et les objets
communiquent beaucoup entre eux. Ainsi, l'abstraction facilite la maintenance
d'un code volumineux, dans lequel diverses modifications peuvent intervenir au
fil du temps.
L'abstraction est donc basée sur l'utilisation de choses simples pour représenter
la complexité. Les objets et les classes représentent le code sous-jacent, en
cachant les détails complexes à l'utilisateur. Il s'agit donc d'une extension de
l'encapsulation. Pour reprendre l'exemple précédent, il n'est pas nécessaire de
connaître tous les détails du fonctionnement du moteur d'une voiture pour
pouvoir la conduire.
Le principe d'héritage
L'héritage définit des relations hiérarchiques entre les classes, de sorte que les
attributs et méthodes communs peuvent être réutilisés. En définissant des
attributs et des comportements de base dans une classe, il est possible de créer
des classes secondaires qui étendent la fonctionnalité de la classe principale et
ajoutent des attributs et des comportements supplémentaires. C'est l'une des
clés de la programmation orientée objet.
Exemple basé sur l'animal : on peut utiliser une seule classe d'animaux et
ajouter un attribut de type d'animal qui spécifie le type d'animal. Différents types
d'animaux nécessiteront différentes méthodes, par exemple, les reptiles doivent
pouvoir pondre des œufs et les poissons doivent pouvoir nager. Même si les
animaux ont une méthode commune, comme le déplacement, la mise en œuvre
nécessiterait de nombreuses instructions « si » pour garantir le comportement
idéal en matière de déplacement. Par exemple, les grenouilles sautent, tandis
que les serpents glissent. Le principe de l'héritage résout ce problème.
Le principe de polymorphisme
Le polymorphisme consiste à concevoir des objets qui partagent des
comportements, ce qui permet de traiter les objets de différentes manières. Il
s'agit de la capacité de présenter la même interface pour différents moyens ou
types de données sous-jacents. En utilisant l'héritage, les objets peuvent
remplacer les comportements primaires partagés par des comportements
secondaires spécifiques. Le polymorphisme permet à la même méthode
d'exécuter des comportements différents de deux manières : le remplacement
de méthode et la surcharge de méthode.
Exercice 1 :
On souhaite développer un programme de gestion des menus. Le programme comporte deux
classes : Ingredient et Menu.
La classe Ingredient est caractérisée par les attributs suivants
• libelle de type String : il définit le nom de l’ingrédient ;
• quantite de type double : il définit la quantité de l’ingrédient utilisée dans un menu ;
• prix de type double : il définit le prix.
La classe Ingredient est caractérisée par les méthodes suivantes :
• un constructeur par défaut ;
• un constructeur avec arguments ;
• des accesseurs et des modificateurs ;
• Une méthode afficher qui permet d’afficher les information sur un ingrédient ;
• une méthode calculerCout qui permet de calculer le coût d’un ingrédient en fonction du prix
et de la quantité et retourne la valeur. Le calcul du coût se fait comme suit :
• cout = prix*quantite ;
La classe Menu est caractérisée par les attributs suivants :
• nom de type String : il définit le nom du menu ;
• prix de type double : il définit le prix de vente d’un plat du menu ;
• cout de type double : il définit le coût du menu (il dépend des ingrédients utilisés pour faire
le menu) ;
• vente de type double : il définit le montant total vendu ;
• quantite de type int : il définit le nombre de plats disponibles ;
• ingredients de type ArrayList<Ingredient> : il définit la liste des ingrédients utilisés pour
constituer le menu.
La classe Menu est caractérisée par les méthodes suivantes :
• un constructeur par défaut ;
• un constructeur avec arguments ;
• une méthode afficher qui permet d’afficher les information du menu ;
• une méthode ajouterIngredient qui prend en paramètre un ingrédient et l’ajoute dans la liste
des ingrédients du menu ;
• une méthode calculerCout qui calcule le coût d’un menu en fonction des ingrédients
utilisés.
• Une méthode ajouterVente qui prend en argument un paramètre nbrePlatAchete et calcule
le montant total vendu et diminue le nombre de plats disponible comme suit :
• vente = vente + nbrePlatsAchte*prix
• quantite = quantite - nbrePlatAchete
1. Donner une implémentation des classes Ingredient et Menu.
2. Implémenter une méthode main qui permet de :
• créer un menu quelconque ;
• créer deux ingrédients quelconques;
1
• ajouter les deux ingrédients créés dans le menu précédemment créé ;
• vendre deux plats
• afficher les informations du menu
L'implémentation des classes Ingredient et Menu en Python, ainsi qu'une méthode main
pour effectuer les opérations demandées.
Implémentation des Classes Ingredient et Menu
python
class Ingredient:
def __init__(self, libelle="", quantite=0.0, prix=0.0):
[Link] = libelle
[Link] = quantite
[Link] = prix
def get_libelle(self):
return [Link]
def set_libelle(self, libelle):
[Link] = libelle
def get_quantite(self):
return [Link]
def set_quantite(self, quantite):
[Link] = quantite
def get_prix(self):
return [Link]
def set_prix(self, prix):
[Link] = prix
def afficher(self):
print(f"Ingredient: {[Link]}, Quantité: {[Link]}, Prix:
{[Link]}")
def calculerCout(self):
return [Link] * [Link]
class Menu:
def __init__(self, nom="", prix=0.0, quantite=0):
[Link] = nom
[Link] = prix
[Link] = 0.0
[Link] = 0.0
[Link] = quantite
[Link] = []
def afficher(self):
print(f"Menu: {[Link]}, Prix: {[Link]}, Coût: {[Link]}, Vente:
{[Link]}, Quantité: {[Link]}")
print("Ingrédients:")
for ingredient in [Link]:
[Link]()
def ajouterIngredient(self, ingredient):
[Link](ingredient)
[Link] += [Link]()
def calculerCout(self):
[Link] = sum([[Link]() for ingredient in
[Link]])
def ajouterVente(self, nbrePlatAchete):
[Link] += nbrePlatAchete * [Link]
[Link] -= nbrePlatAchete
Implémentation de la Méthode main
python
def main():
# Créer un menu quelconque
menu = Menu(nom="Menu Gourmand", prix=12.5, quantite=10)
# Créer deux ingrédients quelconques
ingredient1 = Ingredient(libelle="Poulet", quantite=1.5, prix=5.0)
ingredient2 = Ingredient(libelle="Riz", quantite=2.0, prix=2.5)
# Ajouter les deux ingrédients créés dans le menu
[Link](ingredient1)
[Link](ingredient2)
# Vendre deux plats
[Link](2)
# Afficher les informations du menu
[Link]()
# Appeler la méthode main
if __name__ == "__main__":
main()
Explications
1. Classe Ingredient :
• Constructeurs : Un constructeur par défaut et un avec arguments pour initialiser les
attributs.
• Accesseurs et Modificateurs : Méthodes get et set pour accéder et modifier les
attributs.
• Méthode afficher : Affiche les informations de l'ingrédient.
• Méthode calculerCout : Calcule le coût de l'ingrédient en fonction du prix et de
la quantité.
2. Classe Menu :
• Constructeurs : Un constructeur par défaut et un avec arguments pour initialiser les
attributs.
• Méthode afficher : Affiche les informations du menu et les ingrédients utilisés.
• Méthode ajouterIngredient : Ajoute un ingrédient à la liste et met à jour le
coût du menu.
• Méthode calculerCout : Calcule le coût total du menu en fonction des
ingrédients utilisés.
• Méthode ajouterVente : Calcule le montant total vendu et met à jour la quantité
de plats disponibles.
3. Méthode main :
• Crée un menu et deux ingrédients.
• Ajoute les ingrédients au menu.
• Effectue une vente de deux plats.
• Affiche les informations du menu.
Exercice 5 : classe abstraite En informatique, une Pile est une structure de données fondée sur le
principe dernier arrivé, premier sorti. En informatique, une Pile est une structure de données fondée
sur le principe premier arrivé, premier sorti. On souhaite implémenter une classe Pile destinée à la
gestion des piles d'entier et une classe File destinée à la gestion des files d’entier. On fait
l’hypothèse qu'une Pile et une File sont des sorte de Sac. La classe Sac est caractérisée par : • une
liste d'éléments qui le compose • un constructeur par défaut • un méthode empiler qui prend en
paramètre un entier et qui l'empile; • d'une méthode abstraite depiler qui retourne l'élément dépilé •
d'une méthode estVide qui permet de vérifier si un sac est vide et qui retourne un booléen • d'une
méthode affiche qui affiche les éléments d'un Sac. 1. Donner une implémentation de la classe Sac.
2. Donner une implémentation de la classe Pile et de la classe File sachant qu'elles héritent de la
classe Sac.
Pour commencer, nous allons implémenter la classe abstraite Sac en Python, puis nous créerons les
classes Pile et File qui hériteront de cette classe.
Implémentation de la Classe Abstraite Sac
La classe Sac contient une liste d'éléments, un constructeur par défaut, une méthode empiler,
une méthode abstraite depiler, une méthode estVide et une méthode affiche.
python
from abc import ABC, abstractmethod
class Sac(ABC):
def __init__(self):
[Link] = []
def empiler(self, element):
[Link](element)
@abstractmethod
def depiler(self):
pass
def estVide(self):
return len([Link]) == 0
def affiche(self):
print("Éléments dans le sac:", [Link])
Implémentation de la Classe Pile
La classe Pile hérite de Sac et implémente la méthode depiler en utilisant le principe de LIFO
(Last In, First Out).
class Pile(Sac):
def depiler(self):
if [Link]():
return None
return [Link]()
# Exemple d'utilisation de la classe Pile
pile = Pile()
[Link](1)
[Link](2)
[Link]() # Affiche: Éléments dans le sac: [1, 2]
print("Dépiler:", [Link]()) # Affiche: Dépiler: 2
[Link]() # Affiche: Éléments dans le sac: [1]
Implémentation de la Classe File
La classe File hérite de Sac et implémente la méthode depiler en utilisant le principe de FIFO
(First In, First Out).
class File(Sac):
def depiler(self):
if [Link]():
return None
return [Link](0)
# Exemple d'utilisation de la classe File
file = File()
[Link](1)
[Link](2)
[Link]() # Affiche: Éléments dans le sac: [1, 2]
print("Dépiler:", [Link]()) # Affiche: Dépiler: 1
[Link]() # Affiche: Éléments dans le sac: [2]
Explications
1. Classe Sac:
• Constructeur (__init__) : Initialise une liste vide elements.
• Méthode empiler : Ajoute un élément à la liste elements.
• Méthode abstraite depiler : Doit être implémentée par les classes dérivées.
• Méthode estVide : Vérifie si la liste elements est vide.
• Méthode affiche : Affiche les éléments de la liste elements.
2. Classe Pile:
• Implémente la méthode depiler en utilisant le principe LIFO, en retirant et en
retournant le dernier élément de la liste elements.
3. Classe File:
• Implémente la méthode depiler en utilisant le principe FIFO, en retirant et en
retournant le premier élément de la liste elements.
Exercice 2
On souhaite implémenter une classe Reservoir caractérisée par
les attributs
capacité qui définit la quantité maximale de carburant que peut contenir le reversoir ;
contenu qui définit la quantité de carburant dans le réservoir ;
consommation qui définit la quantité consommée ;
les méthodes
ajouterCarburant : qui permet d’ajouter une quantité passée en paramètre. La méthode ne
retourne rien ;
remplirReservoir : qui permet de remplir le réservoir et qui retourne la quantité ajoutée.
viderReservoir : qui permet de vider le réservoir et qui retourne la quantité vidée.
A faire
1. Proposer une implémentatio de la classe Reservoir.
2. Créer dans la classe main un objet reser de type Reservoir dont la capacité est de 100 litres
et ayant un contenu initial de 30 litres.
3. Ajouter 20 litres au réservoir reser en appelant la méthode ajouterCarburant.
4. vider le réservoir reser en appelant la méthode viderReservoir.
5. afficher la quantité vidée. (0,5 point)
NB : l’implémentation d’un constructeur est obligatoire.
Voici l'implémentation de la classe Reservoir en Python, ainsi que le code pour créer un objet
reser, ajouter du carburant, vider le réservoir, et afficher la quantité vidée.
Implémentation de la Classe Reservoir
python
class Reservoir:
def __init__(self, capacite, contenu, consommation=0):
[Link] = capacite
[Link] = contenu
[Link] = consommation
def ajouterCarburant(self, quantite):
if [Link] + quantite <= [Link]:
[Link] += quantite
else:
print("Quantité ajoutée dépasse la capacité du réservoir.
Remplissage au maximum.")
[Link] = [Link]
def remplirReservoir(self):
quantite_ajoutee = [Link] - [Link]
[Link] = [Link]
return quantite_ajoutee
def viderReservoir(self):
quantite_videe = [Link]
[Link] = 0
return quantite_videe
# Fonction principale pour tester la classe Reservoir
def main():
# Créer un objet Reservoir avec une capacité de 100 litres et un contenu
initial de 30 litres
reser = Reservoir(capacite=100, contenu=30)
# Ajouter 20 litres au réservoir
[Link](20)
print(f"Contenu après ajout de carburant: {[Link]} litres")
# Vider le réservoir
quantite_videe = [Link]()
print(f"Quantité vidée: {quantite_videe} litres")
# Appeler la fonction main
if __name__ == "__main__":
main()
Explications
1. Classe Reservoir :
• Attributs :
• capacite : La capacité maximale du réservoir.
• contenu : La quantité de carburant dans le réservoir.
• consommation : La quantité de carburant consommée (non utilisée dans
les méthodes actuelles mais incluse pour la complétude).
• Constructeur (__init__) : Initialise les attributs avec les valeurs fournies en
paramètres.
• Méthode ajouterCarburant : Ajoute une quantité de carburant au réservoir. Si
la quantité totale dépasse la capacité, le réservoir est rempli au maximum et un
message d'avertissement est affiché.
• Méthode remplirReservoir : Remplit le réservoir à sa capacité maximale et
retourne la quantité de carburant ajoutée.
• Méthode viderReservoir : Vide le réservoir et retourne la quantité de carburant
vidée.
2. Fonction main :
• Crée un objet reser de type Reservoir avec une capacité de 100 litres et un
contenu initial de 30 litres.
• Ajoute 20 litres de carburant au réservoir en appelant la méthode
ajouterCarburant.
• Vide le réservoir en appelant la méthode viderReservoir.
• Affiche la quantité vidée.
Exercice 3 (Héritage)
Soit la classe Document caractérisée par
des attributs suivants : sa référence, son titre, la date d’entrée à la bibliothèque, son état
la méthode "afficher" qui permet d’afficher les informations relatives au document.
Dans une bibliothèque, il existe plusieurs types de documents : des livres et des CD.
1. Un livre est une sorte de document et est caractérisé par le nombre de pages
2. Un CD est une sorte document et est caractérisé par le nombre de pistes.
On souhaiterait créer deux classes Livre et CD pour représenter respectivement ces deux types de
document.
a) Quel type de relation existe-t-il entre la classe Document et la classe Livre ?
b) Donner une implémentation de la classe Document.
c) Donner une implémentation des classes Livre et CD en exprimant les relations avec la classe
Document.
d) Créer une classe main qui permet de créer une instance de la classe Livre et une instance de
la classe CD et d’appeler la méthode afficher
a) Quel type de relation existe-t-il entre la classe Document et la classe Livre ?
La relation entre la classe Document et la classe Livre est une relation d'héritage. La classe
Livre hérite de la classe Document, ce qui signifie que Livre est une sous-classe de
Document. Cette relation est également vraie pour la classe CD, qui est une sous-classe de
Document. En termes d'héritage, Livre et CD sont des spécialisations de la classe Document.
b) Implémentation de la Classe Document
python
class Document:
def __init__(self, reference, titre, date_entree, etat):
[Link] = reference
[Link] = titre
self.date_entree = date_entree
[Link] = etat
def afficher(self):
print(f"Référence: {[Link]}, Titre: {[Link]}, Date d'entrée:
{self.date_entree}, État: {[Link]}")
c) Implémentation des Classes Livre et CD
python
class Livre(Document):
def __init__(self, reference, titre, date_entree, etat, nombre_de_pages):
super().__init__(reference, titre, date_entree, etat)
self.nombre_de_pages = nombre_de_pages
def afficher(self):
super().afficher()
print(f"Nombre de pages: {self.nombre_de_pages}")
class CD(Document):
def __init__(self, reference, titre, date_entree, etat, nombre_de_pistes):
super().__init__(reference, titre, date_entree, etat)
self.nombre_de_pistes = nombre_de_pistes
def afficher(self):
super().afficher()
print(f"Nombre de pistes: {self.nombre_de_pistes}")
d) Implémentation de la Classe main
python
def main():
# Créer une instance de la classe Livre
livre = Livre(reference="L123", titre="Python Programming",
date_entree="2023-01-10", etat="Neuf", nombre_de_pages=350)
# Créer une instance de la classe CD
cd = CD(reference="C456", titre="Greatest Hits", date_entree="2023-01-15",
etat="Bon", nombre_de_pistes=20)
# Appeler la méthode afficher pour chaque instance
print("Informations du Livre:")
[Link]()
print("\nInformations du CD:")
[Link]()
# Appeler la méthode main
if __name__ == "__main__":
main()
Explications
1. Classe Document :
• Attributs : reference, titre, date_entree, etat
• Méthode afficher : Affiche les informations relatives au document.
2. Classe Livre :
• Hérite de la classe Document.
• Attribut supplémentaire : nombre_de_pages
• Constructeur : Utilise le constructeur de la classe parent (Document) et ajoute
l'attribut nombre_de_pages.
• Méthode afficher : Appelle la méthode afficher de la classe parent et affiche
le nombre de pages.
3. Classe CD :
• Hérite de la classe Document.
• Attribut supplémentaire : nombre_de_pistes
• Constructeur : Utilise le constructeur de la classe parent (Document) et ajoute
l'attribut nombre_de_pistes.
• Méthode afficher : Appelle la méthode afficher de la classe parent et affiche
le nombre de pistes.
4. Classe main :
• Crée une instance de la classe Livre et une instance de la classe CD.
• Appelle la méthode afficher pour chaque instance pour afficher les informations.