Java et la générécité

Java et la générécité - Java - Programmation

Marsh Posté le 01-02-2006 à 15:53:36    

Salut, dans mon cours à l'université, le prof nous a montré la générécité et les interfaces, malgré ses explications il y a certains points que je n'arrive pas à comprendre.
 
Pourquoi doit-on écrire:
 
Pile unePile;
unePile = new PileArrayList<String>;
 
Au lieu de:
PileArrayList unePile;
unePile = new PileArrayList<String>;
 
 :pt1cable:  
 

Reply

Marsh Posté le 01-02-2006 à 15:53:36   

Reply

Marsh Posté le 01-02-2006 à 16:00:33    

parce que PileArrayList hérite de Pile surement (ou implémente une interface Pile)


---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 01-02-2006 à 16:03:31    

Harkonnen a écrit :

parce que PileArrayList hérite de Pile surement (ou implémente une interface Pile)


 
C'est exact. Mais je ne vois pas pourquoi on doit déclarer la variable de type Pile et non de type PileArrayList. Moi j'ai toujours conçu qu'on déclare une variable d'un type puis on instancie avec le même type.

Reply

Marsh Posté le 01-02-2006 à 16:07:02    

Parce que l'utilisateur de ta pile n'a pas a savoir quelle est l'implémentation derriere. Tout ce qui le concerne, c'est l'interface. Apres, qu'il y ait une ArrayList ou un Canard derriere, il n'a pas a le savoir.

Reply

Marsh Posté le 01-02-2006 à 16:16:58    

lorill a écrit :

Parce que l'utilisateur de ta pile n'a pas a savoir quelle est l'implémentation derriere. Tout ce qui le concerne, c'est l'interface. Apres, qu'il y ait une ArrayList ou un Canard derriere, il n'a pas a le savoir.


 
Oui mais pourquoi alors c'est différent ?
 
Pile unePile
et unePile = new PileArrayList
 
S'il n'a pas a savoir quel interface on utilise dans la classe PileArrayList c'est mal partie parce que on déclare la variable du type de l'interface.

Reply

Marsh Posté le 01-02-2006 à 16:17:29    

Quand une classe hérite d'une classe abstraite il est préférable de déclarer ses variables du type abstrait (c'est moins limitatif et donc plus évolutif)
 
Exemple : Imagine une classe avec un attribut de type Vector. Tu a donc toute une série de méthode qui retournent ou ont des parametres de type Vector (les accesseurs par exemple)
 
Imagine maintenant que tu n'aimes plus la classe Vector (ex : les accès sont synchronized donc moins performant), tu veux changer le type de ton attribut par ArrayList (c'est la même chose mais les accès ne sont pas synchonisés).
Ca va coincer car partout où tu manipulait un Vector tu va devoir changer en ArrayList...
 
Imagine maintenant qu'au départ tu ais définis ton attribut comme une java.utils.List (Vector et ArrayList implémentent List) => a priori, la seule modif à faire sera de changer les new Vector() par new ArrayList()

Reply

Marsh Posté le 01-02-2006 à 16:19:03    

NullDragon a écrit :


S'il n'a pas a savoir quel interface on utilise dans la classe PileArrayList c'est mal partie parce que on déclare la variable du type de l'interface.


tsk tsk tsk.
 
Il n'a pas a savoir l'implémentation.
Pense a l'interface comme a un contrat entre ton objet réel et les objets qui vont le manipuler. Tu t'engages a faire telle et telle chose,  mais pas a dévoiler ton etat interne (le fait que tu ais une list ou pas, ...)

Reply

Marsh Posté le 01-02-2006 à 16:21:25    

NullDragon a écrit :


S'il n'a pas a savoir quel interface on utilise dans la classe PileArrayList c'est mal partie parce que on déclare la variable du type de l'interface.


Faux, c'est exactement le contraire : l'utilisateur de ta pile doit connaitre l'interface et les méthodes qu'elle expose, rien de plus. Il n'a pas à savoir ce qui se cache derrière l'implémentation de cette interface (la classe PileArrayList en l'occurence)
 
[:benou_grilled]

Message cité 1 fois
Message édité par Harkonnen le 01-02-2006 à 16:21:57

---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 01-02-2006 à 16:24:01    

Euh...je n'ai pas très bien compris, mais si c'est pour éviter de changer le nom du type, il faut quand même changer le new partout non ?

Reply

Marsh Posté le 01-02-2006 à 16:25:58    

Harkonnen a écrit :

Faux, c'est exactement le contraire : l'utilisateur de ta pile doit connaitre l'interface et les méthodes qu'elle expose, rien de plus. Il n'a pas à savoir ce qui se cache derrière l'implémentation de cette interface (la classe PileArrayList en l'occurence)
 
[:benou_grilled]


 
Euh...  [:mouais]  
 
Moi je mettrais plutôt:
 
PileArrayList unePile
unePile = new PileArrayList
 
tout comme on écrit:
 
Personne unePersonne
unePersonne = new Personne

Reply

Marsh Posté le 01-02-2006 à 16:25:58   

Reply

Marsh Posté le 01-02-2006 à 16:27:35    

lorill a écrit :

tsk tsk tsk.
 
Il n'a pas a savoir l'implémentation.
Pense a l'interface comme a un contrat entre ton objet réel et les objets qui vont le manipuler. Tu t'engages a faire telle et telle chose,  mais pas a dévoiler ton etat interne (le fait que tu ais une list ou pas, ...)


 
Oui mais on la voit l'implémentation à cause du new PileArrayList de toute façon non ?

Reply

Marsh Posté le 01-02-2006 à 16:28:40    

NullDragon a écrit :

Euh...je n'ai pas très bien compris, mais si c'est pour éviter de changer le nom du type, il faut quand même changer le new partout non ?


tu changes le code de ton objet, mais pas celui de tous les endroits ou tu l'utilise.
 
mais de toutes facons, ca n'est qu'un gain pratique (et avec un bon ide, tu peux le faire de toutes facons), la vrai raison est plus conceptuelle. Maintenant si tu t'obstines, je vais pas insister.

Reply

Marsh Posté le 01-02-2006 à 16:31:05    

lorill a écrit :

tu changes le code de ton objet, mais pas celui de tous les endroits ou tu l'utilise.
 
mais de toutes facons, ca n'est qu'un gain pratique (et avec un bon ide, tu peux le faire de toutes facons), la vrai raison est plus conceptuelle. Maintenant si tu t'obstines, je vais pas insister.


 
Non c'est juste que je ne comprends pas la logique et j'aimerais comprendre :)

Reply

Marsh Posté le 01-02-2006 à 16:33:12    

NullDragon a écrit :

Oui mais on la voit l'implémentation à cause du new PileArrayList de toute façon non ?


je crois que je vois le probleme.
 
1. définition d'un objet
 

Code :
  1. class MonImplementation implements MonInterface
  2. {
  3.   int nombre = 1; 
  4.   public int getNombre()
  5.   {
  6.     return nombre;
  7.   }
  8. }


 
2. définition d'un autre objet sur la même interface
 

Code :
  1. class MonAutreImplementation implements MonInterface
  2. {
  3.   int x = 5;
  4.   int y = 2; 
  5.   public int getNombre()
  6.   {
  7.     return x*y
  8.   }
  9. }


 
On voit bien que les deux objets ont un fonctionnement interne différent, mais implémentent la même interface, non ?
 
3. utilisation de l'objet
 

Code :
  1. public void utilisation()
  2. {
  3.   MonInterface generateur = new MonImplementation();
  4.   delegueLeTraitement(generateur);
  5. }
  6. public void delegueLeTraitement(MonInterface generateur)
  7. {
  8.   System.out.println(generateur.getNombre());
  9. }


 
La, on voit bien que la méthode delegueLeTraitement, qui utilise l'objet, ne connait pas son implémentation.
Et donc, si dans utilisation() tu changes d'implémentation, le reste est identique.


Message édité par lorill le 01-02-2006 à 16:33:33
Reply

Marsh Posté le 01-02-2006 à 16:37:46    

NullDragon a écrit :

Euh...  [:mouais]  
 
Moi je mettrais plutôt:
 
PileArrayList unePile
unePile = new PileArrayList
 
tout comme on écrit:
 
Personne unePersonne
unePersonne = new Personne


mais nom d'un cheveu de Kojak, réflechis un peu !
ta classe PileArrayList implémente l'interface Pile. ce qui veut dire qu'elle doit implémenter obligatoirement toutes les méthodes de Pile. donc on peut écrire que PileArrayList est une Pile.
toi qui sembles aimer les analogies, imagine une interface "Véhicule", qui expose 2 méthodes : accélerer() et tourner().
tu créé ensuite une classe "Voiture" qui implémente Véhicule, et une classe "Moto" qui implémente aussi Véhicule.  tu implémentes donc dans ces classes les 2 méthodes de Véhicule.
tu vas déclarer ensuite 2 véhicules : une voiture et une moto

Code :
  1. Vehicule maMoto = new Moto();
  2. Vehicule maVoiture = new Voiture();


maintenant, que se passe t'il si tu ne connais strictement rien des classes Moto et Voiture ? tu veux par exemple les faire tourner, mais tu ne connais pas le nom de la méthode qui permet de faire ça. tu ne sais même pas si le concepteur de ces classes a pensé à ajouter une méthode pour les faire tourner... Mais : comme tu sais qu'elles implémentent l'interface Vehicule, qui elle même oblige toute classe l'implémentant à implémenter cette méthode, tu peux donc écrire :

Code :
  1. maMoto.tourner();
  2. maVoiture.tourner();


tu saisis le topo ?

Message cité 1 fois
Message édité par Harkonnen le 01-02-2006 à 16:38:23

---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 01-02-2006 à 16:38:57    


je crois que tu es un peu hors sujet, la question n'est pas sur l'utilité d'une interface dans ce sens, mais au niveau de la déclaration.

Reply

Marsh Posté le 01-02-2006 à 16:40:15    

NullDragon a écrit :

Euh ou est passé le new la dedans ??


dans utilisation(), il crée l'objet avant de déleguer le traitement a une autre méthode.
 
typiquement, ca pourrait etre un constructeur qui instancie un de ses attributs, utilisé par la suite par une de ses methode.

Reply

Marsh Posté le 01-02-2006 à 16:41:34    

Désolé les mecs, mais je ne saisi toujours pas la raison du Pile unePile  [:alph-one]

Reply

Marsh Posté le 01-02-2006 à 16:42:13    

[:rofl]
 
belle réussite les pédagogues [:petrus75]

Reply

Marsh Posté le 01-02-2006 à 16:43:09    

lorill a écrit :

je crois que tu es un peu hors sujet, la question n'est pas sur l'utilité d'une interface dans ce sens, mais au niveau de la déclaration.


ben oui, mais s'il ne comprend pas qu'on peut utiliser un pointeur sur une classe dérivée pour initialiser un pointeur sur classe de base, il risque pas de comprendre cette déclaration [:skeye]


---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 01-02-2006 à 16:43:51    

NullDragon a écrit :

Désolé les mecs, mais je ne saisi toujours pas la raison du Pile unePile  [:alph-one]


 
Je te rassure, j'ai compris, je vois a quoi ca sert...mais je ne l'utiliserai jamais.

Reply

Marsh Posté le 01-02-2006 à 16:44:02    

push a écrit :

[:rofl]
 
belle réussite les pédagogues [:petrus75]


c'est harko qui perturbe la classe  [:klem3i1]

Reply

Marsh Posté le 01-02-2006 à 16:44:53    

Harkonnen a écrit :

ben oui, mais s'il ne comprend pas qu'on peut utiliser un pointeur sur une classe dérivée pour initialiser un pointeur sur classe de base, il risque pas de comprendre cette déclaration [:skeye]


d'apres ce que j'ai compris, il a compris qu'il pouvais, mais il n'a pas compris ou était l'interet.
compris ?
 
 
 
 [:klem3i1]

Reply

Marsh Posté le 01-02-2006 à 16:47:57    

Si, il y a un intérêt. C'est rendre le code un peu plus illisible :D

Reply

Marsh Posté le 01-02-2006 à 16:48:08    

lorill a écrit :

c'est harko qui perturbe la classe  [:klem3i1]


j'essaie juste de montrer que je sais faire autre chose que du Win32, du C# ou de l'assembleur [:god]
 

lorill a écrit :

d'apres ce que j'ai compris, il a compris qu'il pouvais, mais il n'a pas compris ou était l'interet.


ben l'exemple que je lui ai pondu peut quand même l'aider à comprendre je pense, non ?
 
 [:klem3i1]  
 


---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 01-02-2006 à 16:48:54    

Ce que je comprends, jusqu'à présent, c'est que:
 
Pile unePile; déclare une variable d'interface.
 
Mais ça mange quoi en hiver une variable d'interface ?  [:wam]

Reply

Marsh Posté le 01-02-2006 à 16:52:11    

NullDragon a écrit :

Mais ça mange quoi en hiver une variable d'interface ?  [:wam]


N'importe quel objet qui l'implémente..

Reply

Marsh Posté le 01-02-2006 à 16:53:26    

NullDragon a écrit :

Ce que je comprends, jusqu'à présent, c'est que:
 
Pile unePile; déclare une variable d'interface.
 
Mais ça mange quoi en hiver une variable d'interface ?  [:wam]


 
Ca descendance  :D

Reply

Marsh Posté le 01-02-2006 à 16:54:34    

une variable d'interface, ca ne veut rien dire.
 
avec "Pile unePile;" tu déclares une variable de type Pile.
 
il se trouve que Pile est une interface, mais ca serait une classe que ca ne changerait rien au probleme.
 
On va faire plus simple.
 
Tu as ton ArrayList. Quand tu ajoutes quelquechose dedans, il te demande un Object. Toi tu lui mets une String. Ca marche, parce que String est un Object.
 
maintenant, s'ils n'avaient pas mis Object, mais String, tu ne pourrais pas mettre d'Integer, d'accord ?
 
ben la c'est pareil. Alors tu va me dire qu'Object n'est pas une interface, mais on s'en fout, c'est le principe qui compte.

Reply

Marsh Posté le 01-02-2006 à 16:57:27    

NullDragon a écrit :


Pile unePile;
unePile = new PileArrayList<String>;


super la généricité[:mlc]

Reply

Marsh Posté le 01-02-2006 à 16:58:12    

rhoo puis tiens, va :
http://penserenjava.free.fr/pens_2 [...] =00#00.003
 
si ca suffit pas, lit tout le site, ca devrait eclaircir pas mal de points, le livre explique mieux que moi.

Reply

Marsh Posté le 01-02-2006 à 17:11:27    

NullDragon a écrit :

Désolé les mecs, mais je ne saisi toujours pas la raison du Pile unePile  [:alph-one]


Je tente :o
 
En gros, il y a deux concepts à piger ici.
 
Le premier, c'est le concept d'Interface.
Une interface, c'est un contrat, ça dit "un objet avec (implémentant) cette interface doit avoir telle, telle et telle propriétés".
C'est une boite noire avec des manettes précises à la surface.
Mais c'est une boite vide, il n'y a rien derrière les manettes et les boutons, c'est juste un exemple si tu veux.
 
 
Ensuite, on implémente l'interface. Ca veut dire qu'on crée de "vrais" objets qui vont respecter les propriétés définies par l'interface.
Ca veut dire qu'ils auront au moins les mêmes manettes et les mêmes boutons que ton exemple (mais peuvent en avoir d'autres en plus).
 
 
Maintenant, on veut utiliser notre interface, parce qu'on a besoin des manettes et des boutons. L'interface en elle même ne fait rien du tout (c'est un exemple), donc on doit utiliser une impléméntation de l'interface, c'est à dire un truc qui marche, ici la PileArrayList.
 
Simplement, tes opérateurs de machinerie (ton code) n'en ont rien à foutre des boutons et des manettes en plus de celles de ton interface. Pire, ça les trouble, ils ne comprennent pas pourquoi la boite que tu leur file (PileArrayList) n'est pas la même que l'exemple sur lequel ils ont appris (Pile).
 
Alors tu planques ta "vraie" boite derrière la boite-example
 
C'est pour ça que tu déclares que tu files la boite example

Code :
  1. Pile unePile


Mais que derrière les manettes et bouton de l'exemple tu mets une vraie boite qui fait quelque chose

Code :
  1. unePile = new PileArrayList


 
De plus ça a un autre gros avantage: imaginons qu'un joyeux jour de Juin tu as un commercial qui arrive et qui te dis "on a une boite qui fait le même boulot que la votre, mais elle est plus petite, plus légère, elle consomme moins et en plus elle fait le café", appelons la PileStack.
 
Classiquement, tu serais obligé de renvoyer tous tes ouvriers en formation (éditer tout ton code) et de leur apprendre à se servir de la PileStack (remplacer toutes les occurences de Pile ou PileArrayList par PileStack), puisqu'actuellement ils savent juste se servir de la Pile et que la PileStack a des boutons et des manettes différents. Ca coute des sous, beaucoup, et ça trouble tes ouvriers qui risquent de se mélanger entre la Pile et la PileStack, et de faire des conneries.
 
Maintenant si le commercial rajoute à son speech "en plus elle implémente l'interface Pile", alors allelluia!
T'as rien à dire à tes ouvriers, tu remplace juste

Code :
  1. unePile = new PileArrayList


par

Code :
  1. unePile = new PileStack


Tes ouvriers, eux, auront toujours leur boite-exemple Pile avec les manettes et les boutons qu'ils connaissent, que derrière la boite ait changé, fasse le café et consomme moins ils s'en foutent, non seulement ça ne les intéresse pas mais ça n'a aucune influence sur leur boulot, donc ils n'ont pas à être au courant.
 
 
Le principe des interfaces c'est ça: éviter que les gens ne soient au courant de choses qui ne les interesse pas, et qu'ils n'ont pas à savoir.
 
Ca permet de découpler le code de l'implémentation, et d'être ensuite beaucoup plus flexible dans l'implémentation et (par la suite) dans les modifications de l'implémentation en faisant bosser ton code sur une abstraction d'objet qui n'existe pas mais qui peut servir de "boite noire" (e.g. d'interface, d'ou le nom) entre ton code à toi et le code de l'objet.
 
Voila, en espérant que c'était à peu près compréhensible.
 
 
(PS: après, l'utilisation d'interfaces a des avantages et des inconvénients bien sûr, mais bon c'est un autre problème, tu auras le temps de piger les inconvénients quand tu auras compris les avantages)


Message édité par masklinn le 01-02-2006 à 17:13:19

---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
Reply

Marsh Posté le 01-02-2006 à 19:55:14    

http://www.google.com/search?hl=en [...] tnG=Search
http://www.google.com/search?hl=en [...] tnG=Search
 
(et à moins que le sujet ait changé en cours de route, faudrait voir a rectifier le titre du topic)


---------------
Hey toi, tu veux acheter des minifigurines Lego, non ?
Reply

Marsh Posté le 01-02-2006 à 20:15:20    

@Masklinn
 
 Chapeau , tu fait de la formation maintenant ? :D Ou le prochain argument sera "Mais en ruby c'est mieux" :lol:


---------------
Si la vérité est découverte par quelqu'un d'autre,elle perd toujours un peu d'attrait
Reply

Marsh Posté le 01-02-2006 à 21:34:59    

esox_ch a écrit :

Chapeau , tu fait de la formation maintenant ?


 [:kbchris]  
 
Parait que quand j'me lance chuis vachement pédagogue, mais c'est ma mère qui dit ça donc faut pas la croire [:el g]  

esox_ch a écrit :

Ou le prochain argument sera "Mais en ruby c'est mieux" :lol:


Bah non, chuis pas vil au point de confuser le pauvre petit [:moule_bite]  

Spoiler :

et en ruby -- ou en python -- tu te fais pas chier avec des interface ou du typage statique, donc l'affaire est classée



---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
Reply

Marsh Posté le 01-02-2006 à 21:36:45    

masklinn a écrit :


Spoiler :

et en ruby -- ou en python -- tu te fais pas chier avec des interface ou du typage statique, donc l'affaire est classée



Spoiler :

tu te fais pas chier non plus avec de la qualité, des perfs ou des outils de refactoring corrects non plus remarque.

Reply

Marsh Posté le 01-02-2006 à 21:41:21    

nraynaud a écrit :

Spoiler :

tu te fais pas chier non plus avec de la qualité, des perfs ou des outils de refactoring corrects non plus remarque.



Spoiler :

Avec les perfs non, les outils de refactoring en Ruby je sais pas mais en Py il y a le Bicycle Repair Man, et avec la qualité je suis franchement pas d'accord, c'est du même niveau argumentatif que "java c'est lent" [:moule_bite]

Message cité 1 fois
Message édité par masklinn le 01-02-2006 à 21:43:47

---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
Reply

Marsh Posté le 01-02-2006 à 21:42:54    

masklinn a écrit :

Spoiler :

Avec les perfs non, avec les outils de refactoring c'est rare que ce soit nécessaire, et avec la qualité je suis franchement pas d'accord, c'est du même niveau argumentatif que "java c'est lent" [:moule_bite]



Spoiler :

C'est vrai que la théorie des types ça sert qu'à occuper les chercheurs et pas du tout à rattraper tes conneries.

Reply

Marsh Posté le 01-02-2006 à 21:45:02    

Spoiler :

exactement

Reply

Marsh Posté le 01-02-2006 à 21:46:09    

nraynaud a écrit :

Spoiler :

C'est vrai que la théorie des types ça sert qu'à occuper les chercheurs et pas du tout à rattraper tes conneries.



Spoiler :

J'vois franchement pas ce que ça vient foutre là


---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed