Jeux Libres

Plateforme de création de jeux vidéo (Le site est en cours de création / réorganisation)


» Les Tutoriaux » Le monde de la programmation orientée objet.

Le monde de la programmation orientée objet.


Voilà alors ici je vais vous expliquez plus en détail comment fonctionnent les classes, les méthodes appelées sur les objets ou les classes, l'héritage. (objet plus généraux vers objet plus particuliers => hiérarchie)

Les interfaces, etc....




Qu'est-ce donc la POO ?


Partie II




Définition



La POO (programmation orientée objet) est une manière d'encoder un programme de manière simple, la POO recherche donc la simplicité de conception et non la performance.
Les langages orienté objets sont donc plus simple à comprendre pour l'homme mais plus long lors de la compilation.

Hiérarchie aux niveau des langages



Le langage machine :


Seul langage assimilable par votre machine. C'est une suite de 0 et de 1. Complexe à comprendre pour l'homme.

Le langage assembleur :


Il fut inventé pour permettre de rendre plus simple l'encodage, car le langage machine est trop complexe pour l'homme. Imaginer que vous devez coder par exemple tout une suite de 0 et de 1, vous ne saurez en fin de compte même plus si cela représente une image, un nombre, du texte, ... (enfin en 2 mot c'est tellement compliqué que ça se fait pas, sauf si vous êtes fou (lol)), on a donc inventé ce langage qui contient des instructions du genre charger un registre d'un processeur avec une valeur en mémoire centrale, ou une valeur tapée au clavier, utilisation de structures répétitives et alternatives, ... (enfin bref je ne vous apprendrez pas ce langage, il ne s'utilise plus beaucoup,je n'ai pas beaucoup appris ce langage, et avec les processeurs actuels, on sais quand on commence mais pas quand on fini, ce langage et juste utiliser pour par exemple faire marcher un processeur correctement.

Mais pas encore de fonctions avec ce langage.

L'inconvénient majeur de ce langage c'est que chaque processeur à un langage assembleur bien à lui propre, et donc un programme qui est codé pour un processeur intel ne marcheras pas sur une machine ayant un processeur AMD.

Les langages évolués


Ensuite nous avons les langages de troisième génération, langages évolués.
Eux ils ont l'avantage de fonctionner avec n'importe quel type de processeur.
Il y a notamment les langages procéduraux connus comme le C, le Pascal, le Visual Basic et plein d'autres.
Ceux-ci ont la particularité de décomposer les programmes en fonctions.
Le procédural s'intéresse donc surtout aux grandes fonctionnalités que va devoir gérer votre programme.

Et enfin il y a les langages de POO, eux, ils ne s'intéressent pas uniquement aux grandes fonctionnalités du programme, mais aussi aux différents acteurs de ce programme.

Tout ces acteurs sont considéré comme des objets, et chacun possède ses propres caractéristiques et ses propres fonctionnalités.

On fait donc deux découpes dans le code, d'abord on découpe le programme en fonction des grands acteurs de celui-ci et ensuite on découpe le programme en fonction des grandes fonctionnalités que doivent accomplir ces acteurs.

Exemple pour bien comprendre



On doit créer un mmorpg avec des personnages et chaque personnage appartient à une classe bien particulière. (guerrier, magicien, marchand, voleur, ninja, taekwan, fusilleur, chasseur à l'arc, etc...)
Bah on va donc commencer en POO à s'intéresser à coder la classe Personnage qui contiendra des fonctions (méthodes) et caractèristiques (variables) qui seront communes à tout ces personnages.
Ensuite on va s'intéresser aux classes qui auront des fonctions plus spécifique chacune.
Le magicien par exemple pourra lancer des sors avec un bâton.
Le guerrier aura une épée et une cheval par exemple.
Le ninja pourra utiliser des shuriken et des kunaï pour se battre.
Le taekwon attaquera avec ses pieds.
Le marchand lui sont but sera de vendre un max d'objets, il faudra donc qu'il puisse vendre, etc ...
On fait donc 2 découpes :
Quels sont les objets de notre programme et que peuvent ils faire ?
Il y a aussi là une hiérarchie d'objets plus généraux (un personnage) vers des objets plus spécifiques (des magiciens), celà s'appelle l'héritage, je vous en parlerai plus loin dans la POO.

Conséquences de la POO:

Dépendance fonctionnelle : chaque objets devront être modifié avec les méthodes de la classe à laquelle il appartient.

Indépendance de développement : Chaque classe agit indépendamment d'une autre.


Les notions de base


Je vais peut-être me redire mais mieux vaut que je le fasse, surtout sur ces notions fondamentales à absolument maîtriser.

Un objet c'est quoi ?

Bah en fait il n'est pas vraiment possible de définir précisément ce qu'est un objet, ça peut être n'importe quoi, se sera à vous de voir en fonction du jeux que vous voulez créer, quels seront les objets de votre jeux.

Les deux partie d'un objet



Un objets aura toujours deux parties :

une partie statique :
Ce sont les variables propres à chaque objets.

Exemple : sa taille de type entier.

et une partie dynamique :
Ce sont les méthodes qui permettent de modifier la valeur des variables pour un objet. Ceci définit le comportement de l'objet.

Toutes les variables et méthodes propre à un type d'objet devront se retrouver dans sa classe!!

Une classe d'objets c'est quoi ?

C'est tout simplement un genre de moule qui permet de créer des objets, une sorte d'usine si vous voulez.
Pour chaque objets que vous devrez créer, il faudra donc lui définir une classe avec ses caractéristiques.

Exemple, on veut créer des objets de type Voiture.

On souhaite lui définir une couleur (un entier) et une marque (un String).

Ensuite on souhaite pouvoir la faire avancer.
Bah voici ce que ça va donner en java :
Code de la classe voiture :
Code : Java

public class Voiture {
      int couleur;
      String marque;
      int position;
      public void move (int depalcement) {
          position += deplacement;
      }
} 
 

Code de la classe principale contenant le main.
Code : Java

public class TestVoiture {
     public static void main (String[] args) {
         Voiture v1 = new Voiture ();
         v1.couleur = 3;
         v1.marque = "Peugeot";
         v1.move (50);
         System.out.println("Couleur de la voiture : "+v1.couleur+"marque : "+v1.marque +"position : "+v1.position);     
     }
}
 

Essayez.

Il y aura donc 2 choses que vous serez amener à faire : utiliser des méthodes de classes d'objets déjà définies et créer vous même vos propres classes.

Pour bien comprendre je vous invite maintenant à ouvrir blue-J.

Manipulations



Maintenant je vais vous faire effectuer quelques manipulations pour vous bien comprendre le rôle des classes et des méthode sur les objets.^^

Plus tard, nous apprendront à sortir de blue-J et à effectuer toutes les manipulations nécessaire dans un main, mais pour pas tout mélanger, nous allons (contrairement aux exercices précédents ou je vous ai fait tout écrire dans une seule classe, celle du main) ne plus utiliser cette classe avec le main pour l'instant.
Nous nous intéresserons uniquement aux classes, méthodes et objets.^^

En effet, jusqu'ici donc je vous ai fait utiliser que une seule classe dans les exercices, la classe du main, on a donc fait pratiquement que du procédural jusqu'à maintenant.

Bon maintenant je vous invite à cliquer sur projet, open project, shapes.
Il est normalement dans le répertoire C:\blueJ\examples

La vous devriez voir apparaitre une séries de rectangles qui sont en faîtes, des classes.

Faîtes clique droit puis compiler pour les compiler.
On ne va s'intéresser que aux classes triangle, circle et square pour le moment, la classe Canvas est trop complexe.
Faîtes un coup un clic droit sur la classe Triangle et après sélectionner new Triangle ().
Laissez triangle1 dans le champ Name Of Instance qui est le nom référençant votre objet.
Puis vous voyez en dessous normalement apparaître un objet triangle1 de type Triangle!!
Comme sur l'image ci dessous :

Cliquer dessus (clic droit) et vous voyez toute une série de méthodes!
Un genre à l'image ci dessous : (Ne vous étonnez pas si vous n'avez pas les mmême méthodes, j'ai prit les images sur des classes que j'ai faîtes.)

Avec certaines, des arguments entre les ().
Pour voir votre triangle, faîtes makeVisible ()
La on voit un triangle qui s'affiche.
Maintenant vous pouvez modifier sa taille par exemple.
Cliquer sur changeSize et entrer la largeur et la hauteur que vous voulez donnez à votre triangle.
On peut aussi le faire décaler à droite et à gauche, avec les méthode moveRight et moveLeft, etc ...
Vous aller maintenant analyser le code de la classe Triangle, pour cela, clic droit sur la classe Triangle puis vous faîtes "open editor".
Si vous voulez consulter la valeur des variables de votre objet, cliquer tout en bas sur inspect et vous avez normalement une fenêtre de ce genre ci :

Cette classe que contient - elle ?
Ouvrez donc l'éditeur de la classe Triangle maintenant.
Vous voyez que on a d'abord importer un répertoire de java qui est awt, je vous expliquerai plus loin ce qu'il contient.
On voit que pour donner un nom à la classe il est écrit :
public class Triangle {

Et en dessous ?
En dessous on a les attributs ou variables du triangle :
sa hauteur (un entier), etc ...

Après la déclaration des variables, on a ce que l'on appelle un constructeur.

C'est quoi ça un constructeur ???

Ce sera l'objet du tutoriel suivant.^^
Et les méthodes

En dessous, enfin on a les méthodes avec leurs corps.
Voilà donc le code de base d'une classe en Java qui crée des objets.^^
Maintenant vous pouvez aussi analyser celui de la classe Square et celui de la classe Circle.

Je vous invite à dessiner une maison avec blue-j^^.
Sympa non ?

Remarque : vous remarquerai sans doute (ceux qui font du c++), qu'il n'y à pas d'instruction "delete" dans le code ni de destructeurs, c'est normal car les objets en Java sont viré automatiquement de la mémoire dès qu'ils ne sont plus utilisé dans le programme, il y a en Java ce que l'on appelle le "garbage collector" (collecteur de crasses), qui supprime de la mémoire les objets (qui ne sont plus utilisés dans le programme) automatiquement pour vous.

Le cycle de vie d'un objet est donc :

1) Sa création. (avec le mot clef new = l'instanciation)
2) Une série de modifications. (avec l'appel des méthodes sur nos objets)
3) Sa mort (le "garbage collector" s'en charge pour nous)

Vous pouvez créer dans chacune de vos classe une méthode main pour la tester!

A l'exécution, une seule méthode main sera exécutée, même si vous en avez plusieurs dans vos différentes classes.
On verra cela lorsque l'on fera des jar files ou on devra préciser la classe contenant la méthode main qui démarrera notre programme lorsqu'on le lancera.


Le constructeur


C'est quoi un constructeur ?

C'est une méthode particulière qui sert à donner une valeur par défaut aux variables présentes dans votre classe. Donc, on peut, lorsque vous créer un objet avec l'opérateur new, donner une valeur par défaut aux variables de cet objet.

Le constructeur porte le même nom que la classe et n'admet aucun type de retour, même pas void!!

Si vous ne définissez pas de constructeur dans votre classe, un constructeur est automatiquement appelé par défaut et donne une valeur par défaut à toutes les variables de votre classe.

Les valeurs par défault des variables

La valeur par défaut pour les nombres, c'est zéro, et pour les autres variables (variables d'instance), c'est la valeur particulière null. (qui veut dire vide)
Pour les variables de type char c'est le caractère null le '\0'.
Pour les variables de type boolean c'est la valeur false.
Lorsque vous déclarer un objet au début d'une classe, sa valeur vaut null.
Donc si vous ne créér pas de constructeur, et si vous voulez utiliser une méthode qui modifie les valeurs de votre objet qui vaut null, ça ne marchera pas!!

Erreur fréquente en Java.

Créer une classe maison, effacer tout le blalabla qui a entre les crochets qui délimitent la classe, et écriver ceci :
Code : Java

private Triangle toit;
public void moveToit () {       
       toit.moveDown ();
}
 

Compiler et faîtes new maison puis faîtes moveToit ()
Là vous avez une belle erreur en exécution car en faîtes, votre objet toit vaut null, en effet, on l'a juste déclaré mais pas créé!
Vous aurez un erreur de type NullPointerException.
Alors il vous faut rajouter un constructeur dans votre classe maison qui s'en chargera.
code Java :
Code : Java

public Maison () {
    toit = new Triangle ();
    toit.changeColor("black");
    toit.makeVisivle ();
}
 

Et là normalement ça devrait marché.
Voilà donc l'utilité des constructeurs, il est conseiller de toujours en avoir au moins un.
Dans chaque classe que vous créerez à partir de maintenant, vous devrez donc définir au moins un constructeur.


Le nombre d'arguments dans votre constructeur doit correspondre avec le nombre d'arguments dans votre new lorsque vous créez un objet.


La surcharges des méthodes et des constructeurs


La signature des méthodes :



C'est ce qui permet au compilateur Java, lorsque vous invoquer une méthode, de reconnaitre la méthode qu'il doit rechercher en mémoire pour pouvoir ensuite l'exécuter.

Mais sur base de quels critères recherche t - il une méthode ?

Sur base de son nom tout d'abord; mais aussi sur base de la liste des types de ses arguments. (le nom des arguments il s'en moque tout comme le type de retour de la méthode)

Le critère sur lequel se base le compilateur lors des appels de méthode s'appelle la signature d'une méthode.
Celles-ci caractérisent donc une méthode (servent d'identifiant pour une méthode si vous voulez)

La signature d'une méthode c'est quoi donc ?

Le nom de la méthode suivit de la liste des types de ses arguments entre les ().
S'il n'y a pas d'arguments dans la méthode, la signature c'est juste le nom de la méthode alors.

Exemple

La signature de la méthode changeSize de la classe Triangle est donc :
changeSize (int, int)

La surcharge des méthodes :



Ce sont des méthodes dans une même classe, qui portent le même nom, mais dont la liste des types de leurs arguments n'est pas la même.

Donc si je veux surcharger la méthode changeSize, il suffit que j'écrive :


public void changeSize (double weigth, double heigth)
signature : changeSize (double, double)


Vous voyez que j'ai plus mit des int mais des double.

Attention, jamais deux fois la même signature dans une même classe!!!

On peut aussi surcharger les constructeurs?
Bah oui bien sûr, pourquoi on ne pourrait pas.
Cela sert lorsque l'on doit donner des valeur par défaut différemment aux variables.

Par exemple, il serait mieux dans la classe Triangle, de pouvoir, lors de la création d'un triangle, lui donner soi- même une position initiale.

Je veux dans ma classe maison, positionner le toit dans le coin supérieur gauche de l'écran (coordonnées : (0, 0))
D'où l'utilité de créer une surcharge du constructeur de la classe triangle.
Rajouter en dessous du constructeur de la classe triangle ceci.
Code : Java

public Triangle (int vx, int vy) {
       xPosition = vx;
       yPosition = vy;
       width = 40;
       height = 30;
       color = "black";
       isVisible = false;       
}
 

Faîtes new triangle (int vx, int vy) et donnez lui une position en entrant les deux valeurs dans les champs.

Ensuite dans la classe Maison ajouter (0, 0) après le new Triangle comme ceci :
Code : Java

toit = new Triangle (0, 0);
 


Voilà, il n'est plus à la même place, vous pouvez faire la même chose avec la variable color, etc...
Mais n'oublier pas d'initialiser toutes les variables de votre classe dans le constructeur sinon ça fait un joli bug.


L'encapsulation


C'est quoi encore de ce truc vous allez me dire.

Bah en fait c'est simple à comprendre.

Encapsulation :

Chaque variables d'instance ou objet, appartient à sa classe et doit se conformer aux méthodes de cette classe, seul les méthodes de cette classe peuvent modifier la valeur des variables membre de ses objets.
Donc les variables sont, comme vous le constater dans la classe Triangle, déclarées private ça veut dire qu'on ne peut pas y accéder directement. (à partir une autre classe)

On ne peut pas écrire dans une autre classe par exemple
triangle.x = 5;

x est privé et n'est pas accessible en dehors de la classe Triangle.

Il faudra utilisé obligatoirement une méthode de la classe Triangle qui va modifier la valeur de x.

Il faudra aussi en créer une pour récupérer la valeur de x.
Ce sont ce qu'on appelle des getters et des setters. (aussi connus sous le nom d'accesseurs et mutateurs)


Les setters :
Code : Java

public void setX (int nvX) {
    x = nvX;
}
 

Les getters :
Code : Java

public int getX () {
    return x;
}
 


Ainsi pour récupérer le contenu de x dans une autre classe, on écrira :
valeur = triangle.getX (); (getX est déclaré public donc pas de problème)

Si vous écriver "valeur = triangle.x" ça ne marchera pas car x est déclaré private dans la classe Triangle et n'est donc pas accessible en dehors de celle-ci.
Bien sur il y a parfois des excpetions, comme par exemple quand on écrit tableau.length


Mais c'est pas conseillé car ça ne respecte pas le principe d'encapsulation.

Il se peut aussi que des classes ou méthodes soient private, je verrai cela avec vous plus loin mais c'est assez rare.

A partir de maintenant je vous oblige à déclarer toutes vos variables private et vos méthodes public, et je le ferai aussi.

Si vous ne mettez rien (pas de public, ni de private, ...) alors ce qui suit sera par défaut visible uniquement dans le package ou votre classe se trouve.


Le mot clef this


C'est quoi ce mot ?

[color=red]Il pointe vers l'objet qui est entrain d'être créé ou modifié lors de l'appel d'un constructeur ou d'une méthode sur lui même.
Le mot clef this pointe donc vers l'objet lui même.

utilité de this



Dans la classe Triangle par exemple, vous avez du donner un nom différent dans les arguments de votre constructeur :
Code : Java

public Triangle (int vX, int vY) {
    x = vX;
    y = vY;
}
 

Sinon le compilateur va confondre les arguments de votre constructeur et vos variables d'instances que vous essayer d'initialiser.
Bah grâce au mot clef this, on peut écrire ceci :
Code : Java

public Triangle (int x, int y) {
    this.x = x;
    this.y = y;
}
 

Pratique non ?
this pointe vers l'objet lui même. (celui que l'on crée)
Ainsi le compilateur sais faire la distinction entre vos variables d'instances de l'objet lui même et les arguments de votre constructeur.

Sinon il peut aussi être utilisé lors de la surcharge des constructeurs.
Exemple :
Code : Java

public Triangle (int c, int y) {
    this.x = x;
    this.y = y;
}
public Triangle () {
    this (0, 0);
    //etc ...
}
 

Donc grâce à this, on peut faire appel au premier constructeur dans le second pour éviter de devoir retaper du code.

le "this (0, 0)" doit être la première ligne de votre constructeur!

Sérieusement, moi je trouves ce mot clef vraiment très pratique!


Exercices (Méthodes, classes, objets et constructeurs)


1)
Rajouté une méthode dans les classes Triangles, square et Circle, une méthode moveTo qui permettra de faire bouger une forme à un endroit précis sur l'écran.
2)
Compléter la classe maison afin de créer une maison.
Vous devez mettre dans votre constructeur, un toit, une façade, deux fenêtre et une porte.
Créé un méthode pour déplacer la maison.


Solution des exercices (classes, objets, méthodes et ....)


1)
Il suffit tout simplement de rajouter une méthode moveTo dans chacune de ces 3 classes qui modifie les coordonnées de l'objet créé.
Elle doit recevoir en argument la nouvelle position en x et en y de l'objet.
Ensuite reste plus qu'à remplacer les positions dans le corps de la méthode ce qui donne :
Code : Java

public void moveTo (int x, int y) {
       xPosition = x;
       yPosition = y;
       draw (); //Pour remettre à jour l'écran.
}
 

Voilà ajouter cette méthode aux classes et ça ira =)

2)
Alors là je vous ai demandé de compléter notre classe maison, il faut d'abord modifier le constructeur. Bon je vais centrer le toit, je vais donc voir dans la classe Canvas quel est la largeur de la fenêtre.

Là, il l'a écrit lors de la création de son Canvas, elle vaut 300, et la hauteur aussi.

Je placerai moi donc le toit au départ aux coordonnées 150, 10.
Je vais lui mettre comme taille, 50 de hauteur et 200 de largeur.
N'oublier pas de le rendre visible!

Ensuite il faut créer un rectangle et le placer juste en dessous du toit.
Bon histoire de pas m'ennuyer de trop, je vais surcharger les constructeurs de la classe Triangle et de la classe Square pour leur donner directement leur positon, taille et couleur quand je les créées dans le constructeur de ma classe Maison.

Ce qui me donne en définitif pour la classe Triangle le constructeur suivant :
Code : Java

public Triangle (int x, int y, int h, int w, String Color) {
         xPosition = x;
         yPosition = y;
         this.color = color;
         height = h;
         width = w;
         isVisible = false;
}
 

Et dans ma classe Square :
Code : Java

public Square (int x, int y, int size, String color) {
        xPosition = x;
        yPosition = y;
        this.size = size;
        this.color = color;
        isVisible = false;
}
 

Je vous conseille de faire la même chose dans la classe Circle car on l'utilisera après.
Code : Java

public Circle (int x, int y, int d, String color) {
        xPosition = x;
        yPosition = y;
        diameter = d;
        this.color = color;
        isVisible = false;
}
 

Nah, maintenant qu'on a nos constructeurs bien définit, on peut créé notre maison (enfin!)
Je vais donc vous mettre le constructeur de ma classe maison maintenant :
Code : Java

public Maison () {
        toit = new Triangle (150, 10, 50, 150, "black");
        toit.makeVisible ();
        mur = new Square (90, 60, 120, "red");
        mur.makeVisible ();
        fenetreGauche = new Square (100, 70, 40, "blue");
        fenetreGauche.makeVisible ();
        fenetreDroite = new Square (160, 70, 40, "blue");
        fenetreDroite.makeVisible ();
        porte = new Square (130, 140, 40, "black");
        porte.makeVisible ();
}
 

Et maintenant il reste plus qu'à créer une méthode pour la faire bouger.
Allons y. =)
Voici donc ma méthode^^
Code : Java

public void move (int x, int y) {
        toit.moveTo (x, y);
        mur.moveTo (x - 60, y +50);
        fenetreDroite.moveTo (x + 10, y + 60);
        fenetreGauche.moveTo (x - 50, y + 60);
        porte.moveTo (x - 20, y + 130);
}
 

Voilà si vous comprenez ça, nous pouvons passer à la suite ;)




Nous voyons donc ici que la POO peux s'avérer très pratique. Elle permet de géré la composition des objets grâce aux classes, qui définit les variable et méthodes pour chaque type d'objets, donc pas besoin de redéclarer à chaque fois les variables et méthode lors de la créations de plusieurs objets de même type grâce aux classes.

Les constructeurs permettent une initialisation par défaut des attributs/variables des objets lors de leur création.
Pas besoin de delete ni de destructeur, les objets sont automatiquement supprimés lors de leur inutilité grâce au garbage collector!!
Perso je trouves la Java que c'est quand même bien pratique, c++ j'ai du mal à comprendre avec les delete et les pointeurs sur les objets pouwaaa.



Rédigé par Lo



Hébergeur du site : 1and1.fr



Site de création de Jeux Vidéo
Apprenez à créer vos propres Jeux Video

A propos de la construction du site...
352246 pages ont été consultées sur le site !
Dont 242 pages pendant les 24 dernières heures.

Page générée en 0.132 secondes


Nos partenaires
- Otium Production : Aide aux débutants à créer leurs jeux
- Construis ton jeu en PHP : Apprenez à créer votre jeu en PHP
- A.C.S.E.L. : Club de patinage artistique de Caen


  © 2005-2008 www.jeux-libres.com - Toute reproduction totale ou partielle du contenu de ce site est strictement interdite.