Vous êtes sur la page 1sur 14

Programmation Orientée Objet avec Java

Correction TD : Héritage

Exercice 1:

Le programme Erreur ci-dessous définit les classes E1, E2, E3, E4, E5 et Erreur. Pour
chacune des 5 instructions d'affichage dans la méthode main, indiquez si l'instruction est
correcte ou fausse. Compilez et corrigez le programme pour vérifier vos réponses.
/////////////////////////////////////Correction ////////////////////////////////////////

Exercice 1

1. System.out.println(x.a)
Correct, car une variable d'instance a est déclarée dans la classe de x (E1).

2. System.out.println(y.c)
Faux, car la classe de y (E2) ne dispose pas de la variable d'instance c qui est déclarée
dans une sous-classe (E3).

3. System.out.println(z.b)
Correct, car la variable d'instance b est héritée de la super-classe (E2) de z (qui est de
type E3).

4. System.out.println(v.e)
Faux, car la classe de v (E4) ne dispose pas de la variable d'instance e qui est déclarée
dans une classe parallèle (E3).

5. System.out.println(w.a)
Correct, car la variable d'instance a est héritée d'une super-classe (E1) de w (qui est
de type E5).

Exercice 2 :

Une entreprise a un certain nombre d’employés. Un employé est connu par son nom, son
matricule (qui l’identifie de façon unique) et son indice salarial. Le salaire est calculé en
multipliant cet indice par une certaine valeur qui peut changer en cas d’augmentation générale
des salaires, mais qui est la même pour tous les employés.

1. Ecrivez la classe des employés avec les informations utiles et des méthodes pour afficher
les caractéristiques d’un employé et pour calculer son salaire.
2. Certains employés ont des responsabilités hiérarchiques. Ils ont sous leurs ordres d’autres
employés. Ecrivez une sous-classe des employés qui représente ces responsables en
enregistrant leurs inférieurs hiérarchiques directs dans un tableau. Ecrivez une méthode qui
affiche les inférieurs directs (placés directement sous leurs ordres) et une autre qui affiche
les employés inférieurs directs ou indirects (c’est à dire les subordonnés des subordonnés).
On suppose que la hiérarchie de l’entreprise en pyramidale.
3. Les commerciaux ont un salaire composé d’un fixe et d’un intéressement proportionnel à
leurs ventes. Ecrivez une sous-classe des commerciaux qui contient l’information sur leurs
ventes du dernier mois, une méthode pour mettre à jour cette information et redéfinissez la
méthode de calcul de leurs salaires.
4. Ecrivez une classe représentant tout le personnel de l’entreprise, avec une méthode calculant
la somme des salaires à verser.

Exercice N2
class Employe2{
String nom;
int matricule;
int indiceSalarial;
static int valeur = 12;
Employe2(String n, int m, int i){
nom = n;
matricule = m;
indiceSalarial = i;
}
void ecrire(){
System.out.println(nom + " " + matricule + " " + indiceSalarial);
}
int salaire(){
return indiceSalarial *valeur;
}

class Responsable extends Employe2{


Employe2[] subordonnes;
String titre;
Responsable(String n, int m, int i, Employe2[] t, String ti){
super(n,m,i);
subordonnes = t;
titre = ti;

void afficheSubordonnesDirects(){
Super.ecrire();
System.out.println(" subordonnés: ");
for (int i = 0; i<subordonnes.length; i++){
System.out.println(" ");
subordonnes[i].ecrire();
System.out.println();
}
}
void ecrire(){
System.out.println (nom + " " + matricule + " " + indiceSalarial);
System.out.println (" " + titre);
}
}
class Commercial extends Employe2{
int venteDuMois;
Commercial(String n, int m, int i){
super(n,m,i);
}
void enregistreVentes(int i){
venteDuMois = i;
}
int salaire(){
return (indiceSalarial *valeur)+(venteDuMois/12);
}
}
class Personnel{
Employe2[] tabEmp = new Employe2[100];
int nbEmp = 0;
Responsable[] tabResp = new Responsable[10];
int nbResp = 0;
Employe2 chercherEmploye(int matr){
for (int i=0; i<nbEmp; i++){
if (tabEmp[i].matricule == matr){
return tabEmp[i];
}
}
return null;
}
void ajouterEmploye(Employe2 e){
if (chercherEmploye(e.matricule) == null){
tabEmp[nbEmp] = e;
nbEmp++;
}
}
void ajouterResponsable(Responsable r){
if (chercherEmploye(r.matricule) == null){
ajouterEmploye(r);
tabResp[nbResp] = r;
nbResp++;
}
}

void affichePersonnel(){

for (int i=0; i<nbEmp; i++){


tabEmp[i].ecrire();
System.out.println();
}
}
void afficheHierarchie(){
for (int i=0; i<nbResp; i++){
tabResp[i].afficheSubordonnesDirects();
System.out .println("===================================");
}
}
int totalSalaires(){
int somme = 0;
for (int i=0; i<nbEmp; i++){
somme = somme + tabEmp[i].salaire();
}
return somme;
}
}
class Exercice2{
public static void main(String[] args){
Commercial c1, c2, c3;
c1 = new Commercial("Jean",120,12);
c1.enregistreVentes(1200);
c2 = new Commercial("Alberto",121,12);
c2.enregistreVentes(1100);
c3 = new Commercial("John",122,17);
c3.enregistreVentes(700);
Employe2[] t1 = {c1, c2, c3};
Responsable r1, r2, r3;
r1 = new Responsable("Luis",125,20,t1,"directeur commercial");
Employe2 e1, e2, e3;
e1 = new Employe2("Jerzy",17,15);
e2 = new Employe2("Ivan",19,14);
e3 = new Employe2("Joao",21,14);
Employe2[] t2 = {e1, e2, e3};
r2 = new Responsable("Helmut",77,21,t2,"directeur technique");
Employe2[] t3 = {r1, r2};
r3 = new Responsable("Jan",301,30,t3,"directeur");
Personnel pers = new Personnel();
pers.ajouterEmploye(c1);
pers.ajouterEmploye(c2);
pers.ajouterEmploye(c3);
pers.ajouterEmploye(e1);
pers.ajouterEmploye(e2);
pers.ajouterEmploye(e3);
pers.ajouterResponsable(r1);
pers.ajouterResponsable(r2);
pers.ajouterResponsable(r3);
pers.affichePersonnel();
System.out.println();
System.out.println();
pers.afficheHierarchie();
System.out.printn();
System.out.println ();
System.out.println(pers.totalSalaires());
}

Exercice 3 :
Il s’agit dans cet exercice de proposer une conception modélisant une boîtes aux lettres en Java
orienté-objet.

Une boîtes aux lettres recueille des lettres, des colis et des publicités.

Une lettre est caractérisée par :

 son poids (en grammes)


 le mode d’expédition (express ou normal)
 son adresse de destination
 son format ("A3" ou "A4")

Un colis est caractérisé par :

 son poids (en grammes)


 le mode d’expédition (express ou normal)
 son adresse de destination
 son volume (en litres )

Une publicité est caractérisée par :

 son poids (en grammes)


 le mode d’expédition (express ou normal)
 son adresse de destination

Voici les règles utilisées pour affranchir le courrier :

1. en mode d’expédition normal :


– le montant nécessaire pour affranchir une lettre dépend de son format et de son poids
:
Formule : montant = tarif de base + 1.0 * poids (kilos), où le tarif de base pour une
lettre "A4" est de 2.50, et 3.50 pour une lettre "A3"
– le montant nécessaire pour affranchir une publicité dépend de son poids :
Formule : montant = 5.0 * poids (kilos)
– le montant nécessaire pour affranchir un colis dépend de son poids et de son volume
:
Formule : montant = 0.25 * volume (litres) + poids (kilos) * 1.0;
2. en mode d’expédition express : les montants précédents sont doublés, quelque soit le
type de courrier;
3. seul le courrier valide est affranchi;
4. un courrier n’est pas valide si l’adresse de destination est vide;
5. un colis n’est pas valide si son adresse de destination est vide ou s’il dépasse un volume
de 50 litres.

Les trois méthodes principales liées à la boîte aux lettre sont les suivantes :

1. une méthode affranchir() permettant d'associer à chaque courrier de la boîte, le montant


nécessaire pour l'affranchir. Cette méthode retournera le montant total d'affranchissement du
courrier de la boîte.
2. une méthode courriersInvalides() calculant et retournant le nombre de courriers invalides
présents
dans la boîte aux lettres.

3. une méthode afficher() affichant le contenu de la boîte aux lettre (on indiquera alors quels
courriers sont invalides).

Sur papier, commencez par dessiner une hiérarchie de classes permettant de mettre en oeuvre
la conception suggérée en tenant compte des contraintes mentionnées. Vous spécifierez dans
votre diagramme les classes, les attributs et les entêtes des méthodes (sans les corps). Les
contraintes suivantes devront être respectées :

1. Votre conception doit être faite de sorte à ce qu'aucune des méthodes requises n'ait
besoin de faire de test sur la nature de l'objet auquel elle s'applique.
2. Les classes doivent fournir toutes les méthodes qui leur sont nécessaires.
3. Une classe ne comportera que les méthodes/attributs qui lui sont spécifique.
4. Les modificateurs d'accès devront être clairement spécifiés.
5. Vos classes doivent éviter de dupliquer inutilement des méthodes ou des attributs et elle
seront compatibles avec le programme principal fourni dans le fichier Poste.java.

Implémentez ensuite le programme résultant de votre conception dans le fichier Poste.java

Avec le programme principal fourni, vous devriez avoir une exécution telle que (le prix indique
le coùt d'affranchissement):

Le montant total d'affranchissement est de 47.4


Lettre
Poids : 200.0 grammes
Express : oui
Destination : Chemin des Acacias 28, 1009 Pully
Prix : 7.4 CHF
Format : A3

Lettre
(Courrier invalide)
Poids : 800.0 grammes
Express : non
Destination :
Prix : 0.0 CHF
Format : A4

Publicité
Poids : 1500.0 grammes
Express : oui
Destination : Les Moilles 13A, 1913 Saillon
Prix : 15.0 CHF

Publicité
(Courrier invalide)
Poids : 3000.0 grammes
Express : non
Destination :
Prix : 0.0 CHF

Colis
Poids : 5000.0 grammes
Express : oui
Destination : Grand rue 18, 1950 Sion
Prix : 25.0 CHF
Volume : 30.0 litres

Colis
(Courrier invalide)
Poids : 3000.0 grammes
Express : oui
Destination : Chemin des fleurs 48, 2800 Delemont
Prix : 0.0 CHF
Volume : 70.0 litres

La boite contient 3 courriers invalides

////////////////////////////////correction///////////////////////////////////////////////////////////////
/* Classe pour représenter le courrier
*/

class Courrier {
// retourne le montant n'ecessaire pour affranchir le courrier
// en mode d'exp'edition normal

// on va faire une chose tre`s vilaine parcequ'on ne connait pas les


// m'ethodes abstraites : on va lui donner un corps arbitrairement
// d'efini (car on ne sait pas la d'efinir proprement
// a` ce niveau de la hi'erarchie
public double affranchirNormal(){return 0;};
// la bonne solution consiste a` d'eclarer cette m'ethode comme suit:
// abstract private double affranchirNormal();
// lorsque vous aurez vu le cours 8, expliquez pourquoi...

// les attributs (communs aux lettres et colis):


private double poids;
private boolean express;
private String adresse;

// un constructeur possible pour la classe


public Courrier(double poids, boolean express, String adresse) {
this.poids = poids;
this.express = express;
this.adresse = adresse;
}

// un getter pour le poids (car utile dans les sous-classe)


public double getPoids() {
return poids;
}

// retourne le montant n'ecessaire pour affranchir le courrier.


// elle appelle affranchirNormal et retourne le double de ce montant
// si le mode d'exp'edition est express ('eviter la duplication du code
// qui double le montant dans les m'ethodes affranchir-normal
// des sous-classes)
public double affranchir() {
if (! valide())
{
return 0;
}
else
{
double total = affranchirNormal();
if (express) {
total *= 2;
}
return total;
}
}

// un courrier est invalide si l'adresse de destination est vide


// methode utilis'ee par Boite::affranchir et
// Boite::courriersInvalides
public boolean valide() {
return adresse.length() > 0;
}

@Override
public String toString() {
String s = "";
if (!valide())
{
s+= "(Courrier invalide)\n";
}
s+= " Poids : " + poids + " grammes\n";
s+= " Express : " + (express ? "oui" : "non") + "\n";
s+= " Destination : " + adresse + "\n";
s+= " Prix : " + affranchir() + " CHF\n";
return s;
}

/* Une classe pour repr'esenter les lettres


*/

class Lettre extends Courrier {

//attributs sp'ecifiques aux lettres:


private String format = "";

public Lettre(double poids, boolean express, String adresse, String format){


super(poids, express, adresse);
this.format = format;
}

// red'efinit affranchirNormal()
public double affranchirNormal() {
double montant = 0;
if (format.equals("A4")){
montant = 2.0;
} else {
montant = 3.5;
}
montant += getPoids()/1000.0;
return montant;
}

// inutile de red'efinir la méthode valide() pour les lettres

@Override
public String toString() {
String s = "Lettre\n";
s += super.toString();
s += " Format : " + format + "\n";
return s;
}

}
/* Une classe pour repr'esenter les publicit'es
*/

class Publicite extends Courrier {

public Publicite(double poids, boolean express, String adresse){


super(poids, express, adresse);
}

// redéfinit affranchirNormal()
public double affranchirNormal() {
return getPoids()/1000.0 * 5.0;
}

// inutile de red'efinir la méthode valide() pour les publicités

@Override
public String toString() {
String s = "Publicité\n";
s += super.toString();
return s;
}

/* Une classe pour repr'esenter les colis


*/
class Colis extends Courrier {

//attributs sp'ecifiques aux colis:


private double volume;

public Colis(double poids, boolean express, String adresse, double volume) {


super(poids, express, adresse);
this.volume = volume;
}

// redéfinit affranchirNormal();
public double affranchirNormal() {
// affranchit les colis selon une formule pr'ecise
return 0.25 * volume + getPoids()/1000.0;
}

// ici il faut red'efinir (sp'ecialiser) la re`gle de validit'e des colis


// un colis est invalide s' il a une mauvaise adresse
//ou depasse un certain volume
public boolean valide(){
return (super.valide() && volume <= 50);
}

@Override
public String toString() {
String s = "Colis\n";
s += super.toString();
s += " Volume : " + volume + " litres\n";
return s;
}
}

/* Une classe pour repr'esenter la boite aux lettre


*/

class Boite {

private Courrier[] contenu;


private int index;

// constructeur
public Boite(int max) {
contenu = new Courrier[max];
index = 0;
}

// la méthode demand'ee
public double affranchir() {
double montant = 0.0;
for(int i=0; i < index; ++i){
Courrier c = contenu[i];
montant += c.affranchir();
}
return montant;
}

public int size() {


return index;
}

public Courrier getCourrier(int index) {


if (index < contenu.length)
return contenu[index];
else
return null;
}

// autre m'ethode demandée dans l'interface


// d'utilisation de la classe
public int courriersInvalides() {
int count = 0;
for (int i = 0; i < index; i++) {
if (!contenu[i].valide())
count++;
}
return count;
}

// difficile de fonctionner sans


public void ajouterCourrier(Courrier unCourrier) {
if (index < contenu.length){
contenu[index] = unCourrier;
index++;
} else {
System.out.println("Impossible d'ajouter un nouveau courrier.
Boite pleine !");
}
}

public void afficher() {


for (int i = 0; i < index; i++) {
System.out.println(contenu[i]);
}
}

// PROGRAMME PRINCIPAL (non demandé)


class Poste {

public static void main(String args[]) {


//Cr'eation d'une boite-aux-lettres
Boite boite = new Boite(30);

//Creation de divers courriers/colis..


Lettre lettre1 = new Lettre(200, true, "Chemin des Acacias 28, 1009
Pully", "A3");
Lettre lettre2 = new Lettre(800, false, "", "A4"); // invalide

Publicite pub1 = new Publicite(1500, true, "Les Moilles 13A, 1913


Saillon");
Publicite pub2 = new Publicite(3000, false, ""); // invalide

Colis colis1 = new Colis(5000, true, "Grand rue 18, 1950 Sion", 30);
Colis colis2 = new Colis(3000, true, "Chemin des fleurs 48, 2800
Delemont", 70); //Colis invalide !

boite.ajouterCourrier(lettre1);
boite.ajouterCourrier(lettre2);
boite.ajouterCourrier(pub1);
boite.ajouterCourrier(pub2);
boite.ajouterCourrier(colis1);
boite.ajouterCourrier(colis2);

System.out.println("Le montant total d'affranchissement est de " +


boite.affranchir());
boite.afficher();
System.out.println("La boite contient " + boite.courriersInvalides()
+ " courriers invalides");
}
}