# Programmation D/Programmation orientée objet

* Avant de commencer
* Votre premier programme
* Éléments de base du langage et programmation impérative
* Programmation orientée objet
* Éléments avancés du langage
* Outils
* Annexes
* Conclusion
* Avant de commencer
* Votre premier programme
* Éléments de base du langage et programmation impérative
* Programmation orientée objet
* Éléments avancés du langage
* Outils
* Annexes
* Conclusion
[ Modifier le sommaire ]
Le langage D permet de faire de la programmation orientée objet. Pour cela, il faut passer par l'utilisation des classes. Il est important de distinguer la classe de l'objet. Par exemple, "Humain" est une classe et "Roger" est un objet. Ainsi, la classe est une définition générale ("Un humain est un mammifère avec 2 jambes, 2 bras, un nom et un âge.") alors que l'objet est le pendant concret de cette définition. On parle alors d'instance ("Roger" est une instance de la classe "Humain").
Exprimons cela en langage D
Par convention le nom d'une classe s'écrit avec la 1ère lettre en majuscule.

## Les attributs

Si on reprend l'exemple précédent, les attributs de la classe humain sont :
* le nombre de jambes
* le nombre de bras
* le nom
* l'âge
Soit :
Vous remarquerez l'utilisation du mot private qui signifie que l'on ne peut accéder à tout ce qui suit depuis l'extérieur de l'objet, par opposition à public. Observez l'exemple qui suit :
Par convention, on préfixe les attributs par un tiret bas (underscore) : "_".

## Les méthodes

Les méthodes d'une classe correspondent aux actions. Par exemple, on peut implémenter la méthode "avancer". Pour cela, il faut stocker la position de l'humain, soit :
Dans cet exemple, il y a 2 méthodes :
* getNbJambes
* avancer
On fait avancer robert de +2 et +3 sur la grille (abstrait).

## Constructeur et Destructeur

Les constructeurs et les destructeurs sont des méthodes particulières.

### Constructeurs

Le constructeur permet de construire un objet. La méthode utilisée s'appelle "this". Si l'on reprend l'exemple précédent :
Dans l'exemple précédent, on créé un objet robert de type Humain en précisant qu'il a 2 jambes, 2 bras, que son nom est robert, qu'il a 28 ans et se trouve en x:3 y:5.

### Destructeurs

Le destructeur est appelé par le ramasse-miette (« garbage collector ») pour libérer la mémoire et supprimer l'objet. On peut explicitement demander la destruction de l'objet avec le mot clé delete. Le nom de la méthode destructeur est ~this. Soit :
Si on ne supprime pas l'objet robert explicitement avec le mot clé delete le ramasse-miette (garbage collector) le supprimera tout seul quand l'objet ne sera plus utilisé. On peut donc choisir de gérer ou de ne pas gérer la mémoire.
Vous avez remarqué le destructeur est vide, en effet aucune variable a été créé par le mot clé new par conséquent le garbage collecteur pourra faire son travail correctement quand il sera appelé.

## L'héritage

L'héritage consiste à spécialiser une classe : par exemple, un magicien est un humain. Afin d'éviter de réécrire le code de la classe humain, on réutilise le code et on effectue un héritage, de la manière suivante :
Vous remarquerez l'utilisation du mot-clé super celui-ci permet d'appeler le constructeur de la classe mère (c'est à dire ici le constructeur Humain). Pour construire un magicien on doit lui donner une quantité de mana (pouvoirs magiques), un nom, un age et sa position dans l'espace.

### Les Classes Abstraites

Une classe abstraite est une classe que l'on ne peut pas instancier (c'est à dire dont on ne peut créer un objet). Par exemple, on peut décider que la classe mammifère est abstraite. En effet, un mammifère en tant que tel n'existe pas (par exemple, l'Homme est un mammifère et n'existe qu'en tant qu'homme).
La mise en place d'une classe abstraite se fait de la manière suivante :
Ainsi, on ne pourra pas écrire :
Mais on devra créer une classe Homme qui héritera de la classe abstraite Mammifère.

### Les interfaces

Le langage D ne supporte pas l'héritage multiple. Pour contourner cela, on utilise les interfaces. Une interface liste des fonctions que doit obligatoirement utiliser une classe. Reprenons la classe Humain et demandons à celle ci d'implémenter les méthodes suivantes:
* seReposer
* esquiver
* marcher
* courir
Vous en conviendrez, ces méthodes peuvent-être utilisées par d'autres classes que les Humains mais par l'utilisation d'une interface, on standardise le nom de ces méthodes et on évitera ainsi de se retrouver avec du code comme :
* repos se_reposer regenere
* esquiver evite
* marcher marche
* courir seDepecher
On déclare une interface comme cela :
Et on l'implémente à une classe ainsi :
Je vous invite également à lire le tutoriel traitant de la notion d'interface sur le site du zero (bien que le tutoriel en question soit rédigé pour java, la syntaxe est proche et l'utilisation des interfaces est identique).

## Les exceptions

La gestion des erreurs en D est syntaxiquement identique à celle de java. Par conséquent, vous pouvez jeter un œil sur le site du zero pour en apprendre plus.
Le langage D propose une classe Exception que vous pourrez proposer en héritage à vos propres classes de gestion d'erreur. Vous trouverez la définition de cette classe dans /usr/include/d/object.di . Cette classe étant définie dans object.d, elle n'a pas besoin d'être importé.
Pour commencer, nous allons voir un cas plus simple, celui du dépassement de la taille d' un tableau :
On définit un tableau de 5 éléments et on essaye d'aller sur le 6ème (cela déclenche l'erreur) :
* Lorsque le programme atteint une valeur de 6 pour i, une exception de type ArrayBoundsException est levée.
* Le bloc catch contient justement un objet de type ArrayBoundsException en paramètre. Nous l'avons appelé e (par convention).
* L'exception étant capturée, l'instruction du bloc catch s'exécute !
* Le message d'erreur personnalisé s'affiche alors à l'écran.
Note : la définition de l'exception ArrayBoundsException se trouve dans le module tango.core.Exception (c'est pour cela qu'on l'importe ici).
Voyons maintenant le cas de la division par zero, avec une classe Exception personnalisée :

## Les templates

Un template permet d'écrire une fonction ou une classe qui peut accepter n'importe quel type de paramètre et qui retourne également n'importe quel type de variable. Prenons en exemple une fonction pour additionner deux nombres. Traditionnellement, vous feriez :
et ainsi de suite. On remarquera que c'est fastidieux et pour pas grand chose !
En D, avec la notion de template, on peut simplifier cela de la manière suivante :
Explication :
* on met en type de retour le type retourné par element1 + element2, par exemple si on additionne un entier avec un flottant le résultat sera un flottant
* le nom du template
* les types que prend le template. Ici il peut prendre 2 types différents, T ou U (T et U peuvent-être de même type). Par défaut, les types T et U sont respectivement du type de element1 et element2
* on retourne le résultat de l'addition
Exemple :
Note: un template se remarque par identifiant!(type)(parametres)
Ici, nous n'avons pas précisé de type, le template prendra donc les types par défaut de T et U. On pourrait demander, lorsque l'on additionne un entier par un flottant de considérer le dernier comme un entier.
Pour cela, il nous suffit de changer la dernière ligne :
Et d'observer le résultat !