Vous êtes sur la page 1sur 8

2016-2017

Corrigé de l’examen de la matière P.O.O- 2ème année Licence - socle commun

Réponses aux questions (02 points)

1) Qu’elle est la première instruction d’un constructeur ?


-La première instruction d’un constructeur peut être soit un super (liste_ paramètres) ou bien
un this (liste_ paramètres).

2) Qu’elle la différence entre une classe abstraite et une interface ?


-La classe abstraite possède au moins une méthode abstraite, tandis qu’une interface ne
possède que des méthodes abstraites (implicitement abstraites sans la peine de les précéder
du mot clé abstract).

3) Combien d’instances peut-on créer à partir d’une classe abstraite ?


-Aucune.
4) Une classe qui ne possède pas le mot extends dans sa définition (on ne lui spécifie pas une classe
mère), possède- t-elle une classe mère ? Si oui laquelle ?

-Oui elle possède une classe mère, c’est la classe Object.

Exercice1 (03 points)

Pour les lignes 1;2;3;4; (mentionnées en commentaires dans le programme principal) vous dites si
c’est juste en précisant ce qui sera affiché, en cas d’erreurs vous donnez la cause.

Solution

● Pour la ligne /*1*/ l’instruction est correcte ; le résultat sera :


aaa
eee

● Pour la ligne /*2*/ l’instruction est correcte ; le résultat sera :


bbb
ddd

1
● Pour la ligne /*3*/, il existe une erreur. En appelant le constructeur sans paramètres de la
classe petit, Java va insérer un appel au constructeur sans paramètres de la classe mère
(grand ici). Or, dans la classe grand on a défini deux constructeurs avec paramètres mais pas
de constructeur sans paramètres 🡺 une erreur.

● Pour la ligne /*4*/, il existe une erreur. Cette fois ci, on fait appel au constructeur petit(String
b , int o), ce dernier, à son tour, il fait appel via l’instruction this() au constructeur sans
paramètres de la même classe, et le processus de la ligne 3 recommence de nouveau🡺 une
erreur.

Exercice2 (05 points)

Indiquez pour chaque ligne s’il y a des fautes. En cas d’erreur vous indiquez, s’elle est signalée
pendant la compilation ou bien l’exécution (indiquez par exemple si c’est un downcasting implicite ou
explicite ; upcasting).

class forme{}
class cercle extends forme{}

public class poly {


public static void main(String [] args){
forme f1=new forme();cercle c1=f1; forme g1=c1;
forme f2=new cercle();cercle c2=f2; forme g2=c2;
cercle c3=new cercle();forme f3=(forme)c3; cercle g3=(cercle)f3;
Object f4=new Object();cercle g4= (cercle)f4;
cercle g5=new cercle();cercle g6 =new cercle();g5=(forme)g6;
}}

Solution

1) forme f1=new forme();cercle c1=f1; forme g1=c1;

L’affectation cercle c1=f1 pose un problème. C’est un downcasting implicite, on ne peut pas affecter
un objet de la classe forme a un objet de la cercle, sauf si l’objet de la classe forme pointe réellement
sur un objet de la classe forme, et il faudra en plus le caster en un objet de la classe fille avant
d’effectuer l’opération d’affectation 🡺 erreur lors de la compilation.

2) forme f2=new cercle();cercle c2=f2; forme g2=c2;

L’affectation cercle c2=f2 pose un problème. Malgré que cette fois ci l’objet f2 pointe réellement sur
un objet de la classe forme, mais c’est un downcating implicite. On n’a pas casté (transtyper) l’objet f2
vers la classe fille : (fille)f2, avant l’exécution de l’affectation 🡺 une erreur lors de la compilation.

3) cercle c3=new cercle();forme f3=(forme)c3; cercle g3=(cercle)f3;

C’est juste, aucune faute !

4) Object f4=new Object();cercle g4= (cercle)f4;

Cette fois ci, l’objet f4 ne pointe pas sur un objet de la classe cercle. Malgré cela, on l’a casté vers la
classe cercle et on l’a affecté à l’objet g4 de la classe cercle. JAVA ne va pas signaler une erreur lors de
la compilation et va laisser la vérification finale jusqu’au moment de l’exécution. Il se dit, puisque

2
l’utilisateur l’a casté en classe cercle, peut être que lors de l’exécution il pointera réellement sur un
objet de la classe cercle. Or, lors de l’exécution, JAVA se rend compte que f4 réellement pointe sur un
objet de la classe forme et par suite l’affectation ne peut être faite et le downcasting explicite échoue
🡺 erreur lors de l’exécution.

5) cercle g5=new cercle();cercle g6 =new cercle();g5=(forme)g6;

Ici l’objet g6 de la classe cercle est casté vers la classe forme, chose totalement correcte, puisque tout
cercle est une forme. Le problème surgit lors de l’affectation. Après que l’objet g6 ait été transtypé
vers la classe forme, il aura un comportement d’un objet de la classe forme, et par suite on se trouve
en train d’essayer d’affecter un objet de la classe forme à un objet de la classe cercle, qui n’est autre
qu’un downcasting implicite 🡺 erreur lors de la compilation.

Exercice3 (05 points)

Pour les lignes, 1;2;3;4;5;6 (mentionnées en commentaires dans le programme principal) vous dites
ce qui va être affiché avec de brèves explications.

Solution

Pour la ligne /*1*/ :


obj est un objet de la classe upclass qui reçoit un objet de la classe downclass, c’est un upcasting,
donc il pointe sur un objet de la classe downclass. Dans la ligne /*1*/ on le caste vers upclass, ceci n’a
aucun effet car c’est déjà un objet de upclass. En invoquant la méthode B() sur cet objet obj , JAVA va
exécuter celle de l’objet sur lequel réellement obj pointe. Puisque obj pointe sur un objet de la classe
downclass, alors c’est la méthode B() de la class downclass qui sera invoquée. Celle-ci va afficher B
de downclass puis elle va exécuter les deux appels restants super.A() ensuite super.B().
Commençons par super.A() : c’est le A() de upclass qui sera appelé, il affiche A de upclass, puis
appelle A(). Ici, le choix de la méthode A() a exécuter se fait en consultant l’objet courant, puisque

3
c’est un objet de la classe downclass (car obj pointe sur un objet de la classe downclass), alors c’est la
méthode A() de l’objet courant qui sera exécutée : A()de downclass! Alors c’est  A de downclass
qui sera affiché, après, on effectue un appel de C(). Il y a un seul C(), celui déclaré dans upclass et il
est hérité par toutes les sous classes de upclass, en l’occurrence la classe downclass. Une fois exécuté,
on aura un affichage C de upclass et l’appel de Super.A() est terminé. Il nous reste l’appel
super.B(). On exécute alors le B() de upclass, elle va afficher B de upclass puis appelle le B() de
l’objet courant, ça sera le B() de downclass. En appelant celle-ci  et étant dans le même contexte, on
va réitérer le même processus déjà effectué jusqu’ici, et celui-ci va se répéter infiniment.
L’ensemble des affichages obtenus jusqu’ici est :
B de downclass
A de upclass 
A de downclass
C de upclass
B de upclass
C’est cet affichage qui va s’afficher en boucle infinie !

Pour la ligne /*2*/ :


C’est idem à la ligne 1, parce que l’upcasting de la ligne 1 n’a aucun effet.

Pour la ligne /*3*/ :


Cette fois ci, la différence par rapport à la ligne 1, réside dans le fait qu’on a créé un objet objj sans
utiliser un upcasting, cela veut dire que l’objet objj pointe réellement sur un objet de la classe
upclass.
On invoque la méthode B() sur l’objet objj, alors c’est celle de la classe upclass qui sera exécutée,
alors on aura l’affichage B de upclass, suivi d’un appel B(), cette fois ci, c’est la méthode B() de
upclass qui sera exécutée car l’objet courant est objj qui pointe sur un objet de la classe upclass. Alors
elle va réappeler une autre fois la méthode B(), cela donne une suite infinie d’appels récursifs sur la
méthode B() de upclass, comme résultat on aura une boucle infinie d’affichage de:
B de upclass
B de upclass
B de upclass.
.
.

Pour la ligne /*4*/ :

4
Une erreur est affichée lors de l’exécution. C’est clair, on essaie de caster l’objet objj de la classe mère
upclass et qui a une référence d’un objet de cette même classe vers la classe fille downclass, chose
qui est impossible.

Pour la ligne /*5*/ :


A ce niveau, l’objet objj a reçu une référence d’un objet de la classe downclass, la méthode A() à
exécuter est celle de la classe downclass.
On aurra alors un affichage A de downclass, suivi d’un appel à C(), qui donne l’affichage C de
upclass.
L’affichage complet sera :
A de downclass
C de upclass

Pour la ligne /*6*/ :


C’est idem à la ligne 5, parce qu’on sait que A() est une méthode d’objet, alors la méthode qui sera
exécutée est celle de l’objet courant sans tenir compte des multitudes et différents castes qui ont été
effectués.
A de downclass
C de upclass

Exercice4 (05 points)

Qu’affiche le programme suivant?

Solution

5
On va présenter les différentes étapes d’exécution via un schéma (les valeurs des variables dans la
mémoire) pour que ça soit plus clair.
On crée un objet de la classe maman qu’on appelle objet et qui pointe réellement sur un objet de la
classe fille, puis on invoque la méthode A(fille o , int p). C’est la méthode de la classe fille qui sera
exécutée.
Nous somme dans le A(..) de la fille, avant la ligne /*3*/, le schéma montre l’état des différentes
variables.

Après l’exécution de l’instruction de la ligne /*3*/


 

Après l’exécution de l’instruction de la ligne /*4*/

6
Dans la ligne /*5*/ on appelle le A() de la classe maman, et on exécute l’instruction de la ligne /*7*/,
puisque obj est un objet de la classe maman, il ne peut manipuler que les variables de l’objet o
(indirectement celles de objet) et qui sont héritées de la classe maman.

Dans la ligne /*8*/ ; on retourne l’objet obj après l’avoir caster en fille et dépiler pour revenir à la
ligne /*5*/, ou on accède à la variable p de l’objet retourné (classe fille) ; et ça sera la variable p
déclarée dans fille et qui est égale à 22 comme le montre le schéma juste ci-dessus. Auquel on ajoute
5 et l’affichage donnera 27 !
Dans la ligne /*6*/ l’affichage sera 53 car on demande d’afficher le p hérité de la classe maman
comme le montre le schéma juste ci-dessus.

7
Maintenant pour la ligne /*2*/, on fait appel à la méthode A(..) via l’objet oo de la classe maman, ce
qui implique l’appel de la méthode de la classe maman en lui envoyant toujours l’objet objet. Cette
fois ci la variable p de l’objet obj (classe maman) contient 53, en lui ajoutant 22 elle devient 75!

Une fois A(..) terminé on revient à l’instruction après le /*2*/ , on affiche alors le p de l’objet oo
(classe maman) et qui est égale à 75 car oo a reçu l’objet objet (pointé par obj dans la méthode A(…))
retournée par la méthode A(..).
Donc ce programme affiche :

27
53
75

Vous aimerez peut-être aussi