OVH Cloud OVH Cloud

Sous-Typage java

11 réponses
Avatar
Vincent YSMAL
Bonsoir,
alors voila, un prof de Programmation Orienté Objet, m'a affirmé quelque
chose ce soir en cour, que je n'ai pas voulu admettre, j'ai donc
testé en rentrant, et ca confirme ce que je pensais, cependant pour être
sur je préfère demander, peut être qu'il y a une astuce qu'il a oublié
de me dire.
Pour faire simple, si une Classe B possede toutes les methodes
(signature), que la Classe A, sans en hériter, et bien on peux placer
une instance de la Classe B dans un tableau de Classe A, car selon lui,
la Class B, serait un sous-type de la Classe A, exemple.

public ClassA
{
public void maMethode(int nb){}
}


public ClassB
{
public void maMethode(int nb){}
}


public ClassC
{
public static void main(String[] args)
{
ClasseA[] leTableauDeA = new ClasseA[2];
leTableauDeA[0] = new ClasseA();
leTableauDeA[1] = new ClasseB(); <= Ca plante à la compile comme je
le pensait, mais le prof dis que ca marche .....
}
}

Donc voila, si quelqu'un à des idées sur ce qu'il a voulu dire.

PS : je n'ai pas confondu avec les notions d'héritage, si d'interface en
Java, qui permettrais en modifiant le code de faire fonctionner, j'ai
bien fait répéter, et il me la écris au tableau, c'est bien cela qu'il
affirme, une Classe B pour être un sous-type de la Classe A, sans pour
autant etre une sous-classe.

Par avance merci de vos remarques.

10 réponses

1 2
Avatar
Eric Jacoboni
Vincent YSMAL writes:

Pour faire simple, si une Classe B possede toutes les methodes
(signature), que la Classe A, sans en hériter, et bien on peux placer
une instance de la Classe B dans un tableau de Classe A, car selon lui,
la Class B, serait un sous-type de la Classe A, exemple.


A mon avis ça confusionne grave...

public ClassA


Syntax error : public class ClasseA

public ClassB


Syntax error : public class ClasseB

public ClassC
{
public static void main(String[] args)
{
ClasseA[] leTableauDeA = new ClasseA[2];
leTableauDeA[0] = new ClasseA();
leTableauDeA[1] = new ClasseB(); <= Ca plante à la compile comme je
le pensait, mais le prof dis que ca marche .....
}
}


Il doit y a voir confusion avec le fait que ClasseA et ClasseB dérivent
toutes les deux de la classe Object, ce qui permet d'écrire :

Object[] tableauDeClasses = new Object[2];

tableauDeClasses[0] = new ClasseA();
tableauDeClasses[1] = new ClasseB();

Mais c'est bien tout ce qu'elles ont en commun... et cela n'a rien à
voir avec les méthodes qu'elles définissent. C'est uniquement parce
que toute classe dérive directement ou indirectement de Object.

j'ai bien fait répéter, et il me la écris au tableau, c'est bien
cela qu'il affirme, une Classe B pour être un sous-type de la Classe
A, sans pour autant etre une sous-classe.


Eh bien, demande lui de te montrer un code qui tourne ;)

--
Éric Jacoboni, né il y a 1414448833 secondes

Avatar
Vincent YSMAL
Vincent YSMAL writes:


Pour faire simple, si une Classe B possede toutes les methodes
(signature), que la Classe A, sans en hériter, et bien on peux placer
une instance de la Classe B dans un tableau de Classe A, car selon lui,
la Class B, serait un sous-type de la Classe A, exemple.



A mon avis ça confusionne grave...


public ClassA



Syntax error : public class ClasseA


public ClassB



Syntax error : public class ClasseB


public ClassC
{
public static void main(String[] args)
{
ClasseA[] leTableauDeA = new ClasseA[2];
leTableauDeA[0] = new ClasseA();
leTableauDeA[1] = new ClasseB(); <= Ca plante à la compile comme je
le pensait, mais le prof dis que ca marche .....
}
}



Il doit y a voir confusion avec le fait que ClasseA et ClasseB dérivent
toutes les deux de la classe Object, ce qui permet d'écrire :

Object[] tableauDeClasses = new Object[2];

tableauDeClasses[0] = new ClasseA();
tableauDeClasses[1] = new ClasseB();

Mais c'est bien tout ce qu'elles ont en commun... et cela n'a rien à
voir avec les méthodes qu'elles définissent. C'est uniquement parce
que toute classe dérive directement ou indirectement de Object.


j'ai bien fait répéter, et il me la écris au tableau, c'est bien
cela qu'il affirme, une Classe B pour être un sous-type de la Classe
A, sans pour autant etre une sous-classe.



Eh bien, demande lui de te montrer un code qui tourne ;)

Bon, pour commencer, j'avoue que j'ai tapé le code assez rapidement, et

j'ai honte de mes petites erreurs de déclaration de classe.
Ceci étant, j'ai 3 ans de pratique de Java derrière moi, et j'assure que
je n'ai pas confondu, donc je précise ce que me disait donc ce prof,
avec correction de mes erreurs de frappe ;)

public class ClassA
{
public void maMethode(int nb){}
}
public class ClassB
{
public void maMethode(int nb){}
}

public ClassC
{
public static void main(String[] args)
{
ClasseA[] leTableauDeA = new ClasseA[2];
leTableauDeA[0] = new ClasseA();
leTableauDeA[1] = new ClasseB(); <= Ca plante à la compile comme je
le pensait, mais le prof dis que ca marche .....

// Et la suite qui est assez surprenante :
for(int i=0;i<leTableauDeA.length;i++)
{
leTableauDeA[i].maMethode(1);
}
}
}


Avatar
Symon
Oui, mais en passant par une interface définissant maMethode(int nb)...

Je pense que c'est ce qu'il voulait dire.

Symon


Vincent YSMAL wrote:
Bonsoir,
alors voila, un prof de Programmation Orienté Objet, m'a affirmé quelque
chose ce soir en cour, que je n'ai pas voulu admettre, j'ai donc testé
en rentrant, et ca confirme ce que je pensais, cependant pour être sur
je préfère demander, peut être qu'il y a une astuce qu'il a oublié de me
dire.
Pour faire simple, si une Classe B possede toutes les methodes
(signature), que la Classe A, sans en hériter, et bien on peux placer
une instance de la Classe B dans un tableau de Classe A, car selon lui,
la Class B, serait un sous-type de la Classe A, exemple.

public ClassA
{
public void maMethode(int nb){}
}


public ClassB
{
public void maMethode(int nb){}
}


public ClassC
{
public static void main(String[] args)
{
ClasseA[] leTableauDeA = new ClasseA[2];
leTableauDeA[0] = new ClasseA();
leTableauDeA[1] = new ClasseB(); <= Ca plante à la compile comme je
le pensait, mais le prof dis que ca marche .....
}
}

Donc voila, si quelqu'un à des idées sur ce qu'il a voulu dire.

PS : je n'ai pas confondu avec les notions d'héritage, si d'interface en
Java, qui permettrais en modifiant le code de faire fonctionner, j'ai
bien fait répéter, et il me la écris au tableau, c'est bien cela qu'il
affirme, une Classe B pour être un sous-type de la Classe A, sans pour
autant etre une sous-classe.

Par avance merci de vos remarques.


Avatar
Vincent YSMAL
Non, non je confirme, je connais bien les principes des interfaces et de
l'héritage, et je garantis que je lui ai posé la question, et que ce
n'est pas ce qu'il voulait dire

Oui, mais en passant par une interface définissant maMethode(int nb)...

Je pense que c'est ce qu'il voulait dire.

Symon


Vincent YSMAL wrote:

Bonsoir,
alors voila, un prof de Programmation Orienté Objet, m'a affirmé
quelque chose ce soir en cour, que je n'ai pas voulu admettre, j'ai
donc testé en rentrant, et ca confirme ce que je pensais, cependant
pour être sur je préfère demander, peut être qu'il y a une astuce
qu'il a oublié de me dire.
Pour faire simple, si une Classe B possede toutes les methodes
(signature), que la Classe A, sans en hériter, et bien on peux placer
une instance de la Classe B dans un tableau de Classe A, car selon
lui, la Class B, serait un sous-type de la Classe A, exemple.

public ClassA
{
public void maMethode(int nb){}
}


public ClassB
{
public void maMethode(int nb){}
}


public ClassC
{
public static void main(String[] args)
{
ClasseA[] leTableauDeA = new ClasseA[2];
leTableauDeA[0] = new ClasseA();
leTableauDeA[1] = new ClasseB(); <= Ca plante à la compile comme
je le pensait, mais le prof dis que ca marche .....
}
}

Donc voila, si quelqu'un à des idées sur ce qu'il a voulu dire.

PS : je n'ai pas confondu avec les notions d'héritage, si d'interface
en Java, qui permettrais en modifiant le code de faire fonctionner,
j'ai bien fait répéter, et il me la écris au tableau, c'est bien cela
qu'il affirme, une Classe B pour être un sous-type de la Classe A,
sans pour autant etre une sous-classe.

Par avance merci de vos remarques.




Avatar
Bruno Jouhier
leTableauDeA[1] = new ClasseB(); <= Ca plante à la compile comme je
le pensait, mais le prof dis que ca marche .....




Donc le prof dit une connerie. Si ça ne compile pas, il n'y a aucune chance
que ça marche!

Il y a juste une chose un peu troublante avec les tableaux Java, c'est que
si B est une sous classe de A, on peut écrire:

B[] arrayOfB = new B[10];
A[] arrayOfA = arrayOfB; // ça compile

Ce qui permet de faire:

arrayOfA[0] = new A();

c-a-d de mettre un A dans un tableau qui a été alloué comme un tableau de B!

Bizarrement, il n'y a aucun cast là-dedans, et pourtant on obtient une
violation de type. Ca sera détecté au run-time, par une ArrayStoreException.

A ma connaissance, c'est le seul point un peu tangent avec le typage des
tableaux. Mais ce que dit ton prof (si tu l'as traduit correctement) n'a pas
de sens.

Bruno.



Avatar
xav
Bruno Jouhier wrote:
leTableauDeA[1] = new ClasseB(); <= Ca plante à la compile comme je
le pensait, mais le prof dis que ca marche .....





Donc le prof dit une connerie. Si ça ne compile pas, il n'y a aucune chance
que ça marche!

Il y a juste une chose un peu troublante avec les tableaux Java, c'est que
si B est une sous classe de A, on peut écrire:

B[] arrayOfB = new B[10];
A[] arrayOfA = arrayOfB; // ça compile

Ce qui permet de faire:

arrayOfA[0] = new A();

c-a-d de mettre un A dans un tableau qui a été alloué comme un tableau de B!

Bizarrement, il n'y a aucun cast là-dedans, et pourtant on obtient une
violation de type. Ca sera détecté au run-time, par une ArrayStoreException.

A ma connaissance, c'est le seul point un peu tangent avec le typage des
tableaux. Mais ce que dit ton prof (si tu l'as traduit correctement) n'a pas
de sens.

Bruno.




quel jdk ?

boh, les profs (de fac) disent souvent des conneries en ce qui concerne
la programmation pure et dure :o)




Avatar
Julien Signoles
Bonjour,

alors voila, un prof de Programmation Orienté Objet, m'a affirmé quel que
chose ce soir en cour, que je n'ai pas voulu admettre, j'ai donc
testé en rentrant, et ca confirme ce que je pensais, cependant pour ê tre
sur je préfère demander, peut être qu'il y a une astuce qu'il a oub lié
de me dire.


Commençons par noter qu'il s'agit d'un prof (donc d'un cours ?) de
Programmation Orienté Objet et pas d'un prof (d'un cours) de java...

Pour faire simple, si une Classe B possede toutes les methodes
(signature), que la Classe A, sans en hériter, et bien on peux placer
une instance de la Classe B dans un tableau de Classe A, car selon lui,
la Class B, serait un sous-type de la Classe A, exemple.


Ton prof a raison dans le cas général, c'est-à-dire le cas où les
relations de sous-typage et d'héritage ne coïncident pas !
Malheureusement, le langage Java est trop restrictif en faisant coïncider
ces deux relations. Par suite, on ne peut pas tester la situation que tu
décris en Java.

public ClassA
{
public void maMethode(int nb){}
}


public ClassB
{
public void maMethode(int nb){}
}


public ClassC
{
public static void main(String[] args)
{
ClasseA[] leTableauDeA = new ClasseA[2];
leTableauDeA[0] = new ClasseA();
leTableauDeA[1] = new ClasseB(); <= Ca plante à la compile com me je
le pensait, mais le prof dis que ca marche .....
}
}

Donc voila, si quelqu'un à des idées sur ce qu'il a voulu dire.

PS : je n'ai pas confondu avec les notions d'héritage, si d'interface e n
Java, qui permettrais en modifiant le code de faire fonctionner, j'ai
bien fait répéter, et il me la écris au tableau, c'est bien cela qu 'il
affirme, une Classe B pour être un sous-type de la Classe A, sans pour
autant etre une sous-classe.


Le code ci-dessus emprunte la syntaxe de java mais pas sa sémantique.
Donc c'est normal qu'il ne fonctionne pas en java. Un exemple de langage
dans lequel cette sémantique est implantée est objective caml. Dans
ce langage, la relation de sous-typage ne suit pas la relation
d'héritage. Cet exemple se traduit dans ce langage comme suit. Bien
entendu, il compile et s'exécute correctement :o).

=== (* code objective caml *)
class a = object
method maMethode (x:int) = x
end

class b = object
method maMethode (x:int) = x
end

let main =
let leTableauDeA = Array.make 2 (new a) in
leTableauDeA.(0) <- new a;
leTableauDeA.(1) <- new b (* aucun problème ! *)
===

Morale de l'histoire : les profs d'info à l'université savent (parfois
;-)) ce qu'ils racontent...

Julien
--
mailto: ; http://www.lri.fr/~signoles
"In theory, practice and theory are the same,
but in practice they are different" (Larry McVoy)

Avatar
Bruno Jouhier
"xav" a écrit dans le message de news:
d1mqfv$cj1$
Bruno Jouhier wrote:
leTableauDeA[1] = new ClasseB(); <= Ca plante à la compile comme je
le pensait, mais le prof dis que ca marche .....





Donc le prof dit une connerie. Si ça ne compile pas, il n'y a aucune
chance que ça marche!

Il y a juste une chose un peu troublante avec les tableaux Java, c'est
que si B est une sous classe de A, on peut écrire:

B[] arrayOfB = new B[10];
A[] arrayOfA = arrayOfB; // ça compile

Ce qui permet de faire:

arrayOfA[0] = new A();

c-a-d de mettre un A dans un tableau qui a été alloué comme un tableau de
B!

Bizarrement, il n'y a aucun cast là-dedans, et pourtant on obtient une
violation de type. Ca sera détecté au run-time, par une
ArrayStoreException.

A ma connaissance, c'est le seul point un peu tangent avec le typage des
tableaux. Mais ce que dit ton prof (si tu l'as traduit correctement) n'a
pas de sens.

Bruno.


quel jdk ?


Ca ne dépend pas du JDK, ce comportement est lié aux specs du langage, pas
au JDK.


boh, les profs (de fac) disent souvent des conneries en ce qui concerne la
programmation pure et dure :o)






Avatar
xav
Bruno Jouhier wrote:
"xav" a écrit dans le message de news:
d1mqfv$cj1$

Bruno Jouhier wrote:

Il y a juste une chose un peu troublante avec les tableaux Java, c'est
que si B est une sous classe de A, on peut écrire:

B[] arrayOfB = new B[10];
A[] arrayOfA = arrayOfB; // ça compile

Ce qui permet de faire:

arrayOfA[0] = new A();

c-a-d de mettre un A dans un tableau qui a été alloué comme un tableau de
B!

Bizarrement, il n'y a aucun cast là-dedans, et pourtant on obtient une
violation de type. Ca sera détecté au run-time, par une
ArrayStoreException.

A ma connaissance, c'est le seul point un peu tangent avec le typage des
tableaux. Mais ce que dit ton prof (si tu l'as traduit correctement) n'a
pas de sens.



quel jdk ?



Ca ne dépend pas du JDK, ce comportement est lié aux specs du langage, pas
au JDK.



Mouais, mais un comportement qui fait a coup sur une erreur à l'exec, ca
serait pas mal qu'elle soit gérée a la compil, d'où ma question un peu
neuneute :o)
Et c'est quel paragraphe dans la jls qui "permet" ça ?

Xavier.



Avatar
Vincent YSMAL
Bonjour,


alors voila, un prof de Programmation Orienté Objet, m'a affirmé quelque
chose ce soir en cour, que je n'ai pas voulu admettre, j'ai donc
testé en rentrant, et ca confirme ce que je pensais, cependant pour être
sur je préfère demander, peut être qu'il y a une astuce qu'il a oublié
de me dire.



Commençons par noter qu'il s'agit d'un prof (donc d'un cours ?) de
Programmation Orienté Objet et pas d'un prof (d'un cours) de java...


Pour faire simple, si une Classe B possede toutes les methodes
(signature), que la Classe A, sans en hériter, et bien on peux placer
une instance de la Classe B dans un tableau de Classe A, car selon lui,
la Class B, serait un sous-type de la Classe A, exemple.



Ton prof a raison dans le cas général, c'est-à-dire le cas où les
relations de sous-typage et d'héritage ne coïncident pas !
Malheureusement, le langage Java est trop restrictif en faisant coïncider
ces deux relations. Par suite, on ne peut pas tester la situation que tu
décris en Java.


public ClassA
{
public void maMethode(int nb){}
}


public ClassB
{
public void maMethode(int nb){}
}


public ClassC
{
public static void main(String[] args)
{
ClasseA[] leTableauDeA = new ClasseA[2];
leTableauDeA[0] = new ClasseA();
leTableauDeA[1] = new ClasseB(); <= Ca plante à la compile comme je
le pensait, mais le prof dis que ca marche .....
}
}

Donc voila, si quelqu'un à des idées sur ce qu'il a voulu dire.

PS : je n'ai pas confondu avec les notions d'héritage, si d'interface en
Java, qui permettrais en modifiant le code de faire fonctionner, j'ai
bien fait répéter, et il me la écris au tableau, c'est bien cela qu'il
affirme, une Classe B pour être un sous-type de la Classe A, sans pour
autant etre une sous-classe.



Le code ci-dessus emprunte la syntaxe de java mais pas sa sémantique.
Donc c'est normal qu'il ne fonctionne pas en java. Un exemple de langage
dans lequel cette sémantique est implantée est objective caml. Dans
ce langage, la relation de sous-typage ne suit pas la relation
d'héritage. Cet exemple se traduit dans ce langage comme suit. Bien
entendu, il compile et s'exécute correctement :o).

=== (* code objective caml *)
class a = object
method maMethode (x:int) = x
end

class b = object
method maMethode (x:int) = x
end

let main > let leTableauDeA = Array.make 2 (new a) in
leTableauDeA.(0) <- new a;
leTableauDeA.(1) <- new b (* aucun problème ! *)
== >
Morale de l'histoire : les profs d'info à l'université savent (parfois
;-)) ce qu'ils racontent...

Julien
Bonsoir,

alors pour faire simple, le cours, ou plutot le TP, était un TP de mise
en pratique de POO en java ... OCaml viendra bientôt.
Ensuite pour les erreurs de sémantique, c'est parce que j'ai tapé un peu
vite, et effectivemtn y a des fautes, mais je voulais seulement faire
passer l'idée générale, mais s'il faut, je peux vous copier coller, le
code exact en JAVA, et pas Ocaml.


1 2