You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.
 
 
 
 
 
 

107 lines
3.0 KiB

  1. Composition
  2. ============
  3. Définition
  4. -----------
  5. Une classe à l'intérieur d'une autre classe.
  6. Dépendances entre fonctions
  7. -----------------------------
  8. Exemple: on veut dessiner un sapin dans le terminal::
  9. def main():
  10. largeur = demander_largeur()
  11. dessine_sapin(largeur)
  12. main()
  13. On voit que la fonction ``dessine_sapin()`` prend un argument ``largeur``, qui est retourné
  14. par la fonction ``demander_largeur()``.
  15. ``dessine_sapin()`` doit donc être appelée *après* ``demander_largeur()``. On dit que ``dessine_sapin()``
  16. _dépend_ de ``demander_largeur()``.
  17. Dépendances entre classes
  18. -------------------------
  19. Un bon moyen d'introduire une dépendance entre deux classes est d'utiliser les constructeurs.
  20. Revoyons la classe Chat::
  21. class Chat:
  22. def __init__(self, nom):
  23. self.nom = nome
  24. Comme le constructeur de la classe Chat prend un nom en argument, il est impossible de construire
  25. des chats sans nom::
  26. >>> chat = Chat()
  27. TypeError: __init__() missing 1 required positional argument: 'nom'
  28. De la même façon, si on veut que tous les enfants aient un chat (pourquoi pas, après tout), on peut
  29. avoir une classe Enfant, dont le constructeur prend une instance de chat en plus du prénom::
  30. class Enfant:
  31. def __init__(self, prénom, chat):
  32. self.prénom = prénom
  33. self.chat = chat
  34. >>> alice = Enfant("Alice")
  35. TypeError: __init__() missing 1 required positional argument: 'chat'
  36. >>> boule_de_poils = Chat("Boule de Poils")
  37. >>> alice = Enfant("Alice", boule_de_poils)
  38. # OK!
  39. Utilisation de la composition
  40. -----------------------------
  41. Maintenant qu'on vit dans un monde où tous les enfants ont chacun un chat, on peut
  42. par exemple consoler tous les enfants en leur demandant de caresser leur chat, chat
  43. qui va ronronner et faire plaisir à son propriétaire.
  44. voici comment on peut coder cela: d'abord, on rajoute les méthodes ``caresse()``
  45. et ``ronronne()`` dans la classe chat::
  46. class Chat:
  47. def __init__(self, nom):
  48. self.nom = nom
  49. def ronronne(self):
  50. print(self.nom, 'fait: "prrrrr"')
  51. def caresse(self):
  52. self.ronronne()
  53. >>> boule_de_poils = Chat("Boule de Poils")
  54. >>> boule_de_poils.caresse()
  55. Boule de Poils fait "prrrrr"
  56. Ensuite, on peut rajouter la méthode ``console()`` dans la classe Enfant,
  57. qui va:
  58. * récupérer l'instance de la classe Chat dans ``self`` - comme n'importe quel attribut
  59. * puis appeler la méthode ``caresse()`` de cette instance::
  60. class Enfant:
  61. def __init__(self, prénom, chat):
  62. self.chat = chat
  63. def console(self):
  64. self.chat.caresse()
  65. >>> boule_de_poils = Chat("Boule de Poils")
  66. >>> alice = Enfant("Alice", boule_de_poils)
  67. # Alice est triste, on la console
  68. >>> alice.console()
  69. Boule de Poils fait "prrrrr"
  70. # Alice est consolée :)
  71. On dit parfois qu'on a *délégué* l'implémentation de la méthode ``console()`` de la classe Enfant
  72. à la méthode ``caresse()`` de la classe Chat.