user@linuxtrack:~ $ python -c 'print("Soyez les bienvenus !")'

Vous n'êtes pas identifié(e).

#1 13-01-2013 16:40:16

WarLocG
#! modo de compet

Les bases du langage Java - partie 2

Sommaire
1.L'Orienté Objet
2.L'héritage
3.Le polymorphisme
4.try..catch..finally
5.La gestion des exceptions
6.Le pattern Singleton

1.L'Orienté Objet

Pour expliquer au mieux l'Orienté Objet, on va se baser sur quelques exemples.

Exemple d'une application visant a créer un personnage, par exemple, pour un jeu de rôle:

Imaginons une application visant a créer un Personnage. Au niveau des informations utiles pour ce Personnage, on souhaitera qu'il ait un nom, un prénom et un age.

L'application, qui pourra être une commande lancée dans le terminal ou une application graphique, voir même un applet java lancée depuis une page web va donc simplement construire un objet Personnage et en afficher les informations qu'on lui aura transmis.

* Le fait de travailler en Objet permet de réutiliser les classes/objets qui ont été créés, avec beaucoup plus de souplesse que le ferait une fonction en procédural (en fait, une classe serait plus proche d'un enregistrement {struct en C/C++, record en pascal/delphi} que d'une fonction). A savoir aussi, on peut créer autant d'entités de cet objet qu'on en a besoin, ils fonctionnent chacun indépendamment (à l'exception d'un singleton que l'on abordera plus loin).

Exemple: on crée un personnage perso1, ayant comme prénom:"Jean", comme nom:"DuJardin" et comme date de naissance: 25-06-1975.
On créera un autre personnage perso2, ayant comme prénom:"Marie", comme nom:"LaClasse" et comme date de naissance:13-09-1994.
Ils disposeront des même attributs (a savoir prenom, nom, dateNaissance) et des même méthodes (a savoir: getPrenom(), getNom() et getAge() ).

Et donc on pourra faire:

[== Java ==]
Personnage perso1 = new Personnage("Jean","DuJardin",25-06-1975);
Personnage perso2 = new Personnage("Marie","LaClasse",19-09-1980);

perso1.getNom(); // sortie -> DuJardin
perso2.getNom(); // sortie -> LaClasse
perso1.getPrenom(); // sortie -> Jean
perso2.getPrenom(); // sortie -> Marie
perso1.getAge(); // sortie -> 37

A ce stade, rien ne m’empêche de créer encore un troisième personnage perso3, de prénom:"Toto", de nom:"Ratata" et ayant pour date de naissance:01-01-1980. Et faire:

[== Java ==]
Personnage perso3 = new Personnage("Toto","Ratata",01-01-1980);

perso3.getNom(); // sortie -> Ratata
perso3.getPrenom(); // sortie -> Toto
perso3.getAge(); // sortie -> 32

* Lorsqu'on parle Objet, on parle aussi en terme d'encapsulation, c'est-à-dire, on règle la visibilité des attributs/propriétés ou des méthodes d'une classe afin de restreindre ou permettre les accès aux parties qui en ont besoin.

En général, les attributs sont déclarées privées, parce que si elles étaient déclarées publiques, il serait possible de les modifier depuis n'importe où.

Exemple, si dans la classe Personnage, on avait déclaré des attributs publiques.

[== Java ==]
...
public String nom;
public String prenom;
public Date dateNaissance;
...

Il serait possible dans un programme, pour autant qu'elle ait accès a la classe Personnage, de faire:

[== Java ==]
Personnage.nom = "NouveauNom"; // accessible depuis n'importe où
// ou
perso1.prenom = "Marcel"; // tiens il s'appelle plus Jean DuJardin mais Marcel DuJardin maintenant.

Lorsqu'on aura besoin de modifier un attribut, on passera par une méthode dite 'setter' ou 'mutateur' pour la modifier.

[== Java ==]
public void setPrenom(String newPrenom)
{
this.prenom = newPrenom;
}

De ce fait, si on veut modifier la valeur de l'attribut prenom, il faudra:
* 1) créer un objet Personnage.
* 2) utiliser la méthode setPrenom("leNouveauPrenom") sur l'objet de type Personnage.

Exemple:

[== Java ==]
Personnage perso4 = new Personnage("A","B",01-01-2013);
perso4.getPrenom(); // sortie -> A
perso4.setPrenom("C");
perso4.getPrenom(); // cette fois, sortie -> C

J'écris ici à la suite les codes sources des classes Personnage et main afin, j'espère, que vous y verrez plus clair une fois que tout est mis ensemble:

Personnage:

[== Java ==]
/* Afin d'éviter des problèmes d'import j'insère quand même toujours les import nécessaires des fois que */
import java.lang.String;
import java.util.*; // Pour utiliser Date et Calendar
import java.text.*; // Pour utiliser SimpleDateFormat et ParseException

public class Personnage
{
  private String prenom;
  private String nom;
  private Date dateNaissance;

  /** Constructeur Personnage */
  public Personnage(String prenom, String nom, Date dateNaissance)
  {
    this.prenom = prenom;
    this.nom = nom;
    this.dateNaissance = dateNaissance;
  }

  /* Getters */

  public String getPrenom()
  {
    return this.prenom;
  }

  public String getNom()
  {
    return this.nom;
  }

  public int getAge()
  {
    /* calcul de l'age sur base de la date de naissance (sur base de la vraie date actuelle et non du "découpages de String") 
     * à façon bête et méchante. Mais vous focalisez pas sur le code, c'est juste histoire de vous permettre de l'essayer sans erreur.
     */
    int age = 0;

    Calendar actuel = Calendar.getInstance();
    Calendar perso = Calendar.getInstance();
    SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy");

    try{
        perso.setTime(sdf.parse(this.dateNaissance));
    } catch (ParseException e){
        e.printStackTrace();
    }
  
    age = actuel.get(Calendar.YEAR) - perso.get(Calendar.YEAR);
    actuel.add(Calendar.YEAR,-age);
    
    if(perso.after(actuel))
    {
      age -= 1;
    }
    
    return age;
  }

  /* Setters */

  public void setPrenom(String newPrenom)
  {
    this.prenom = newPrenom;
  }

}

main:

[== Java ==]
class TutoJavaCyberTrack_POO_1{

  public static void main(String args[])
  {
    // Première série de test

    Personnage perso1 = new Personnage("Jean","DuJardin",25-06-1975);
    Personnage perso2 = new Personnage("Marie","LaClasse",19-09-1980);

    // perso1.getNom(); // sortie -> DuJardin

    // Sort le message sur console, faire pareil pour les autres
    // Pour les autres API, on verra plus tard avec les JFrame, etc..
    System.out.println("perso1: "+perso1.getPrenom()+" "+perso1.getNom()+" Age: "+String.valueOf(perso1.getAge())+" ans"); 
    
    // perso2.getNom(); // sortie -> LaClasse
    // perso1.getPrenom(); // sortie -> Jean
    // perso2.getPrenom(); // sortie -> Marie
    // perso1.getAge(); // sortie -> 37

    Personnage perso3 = new Personnage("Toto","Ratata",01-01-1980);

    // perso3.getNom(); // sortie -> Ratata
    // perso3.getPrenom(); // sortie -> Toto
    // perso3.getAge(); // sortie -> 32

    Personnage perso4 = new Personnage("A","B",01-01-2013);

    // perso4.getPrenom(); // sortie -> A
    // perso4.setPrenom("C");
    // perso4.getPrenom(); // cette fois, sortie -> C
  }
}

2.L'héritage

D'abord un peu de théorie:

L'héritage va permettre de prendre une entité (classe) et lui donner des fonctionnalités propres a sa nouvelle entité mais tout en gardant les fonctionnalités du parent.

Exemple avec les genres:

On va créer une classe Homme héritant de Personnage, ainsi qu'une classe Femme héritant également de Personnage.

Schéma de ce que l'on va réaliser:
1402832034.png

Je n'afficherai que Homme pour éviter de remettre le même code partout.

Pour dire d'une classe qu'elle hérite d'une autre classe on utilisera le mot extends.

[== Java ==]
public class Homme extends Personnage
{
...
}

On va également leur ajouter un constructeur.

Note: comme le constructeur de la classe parent "Personnage" demande 3 arguments : un prénom, un nom et une date de naissance, il faudra les donner aussi aux classes enfants : "Homme" et "Femme".

Petite remarque: le mot super permet d'accéder à la classe parent. Ainsi, super() désignera le constructeur du parent, et super.methode() permettra d'accéder à une méthode de la classe parent.

[== Java ==]
public class Homme extends Personnage
{
   public Homme (String prenom, String nom, Date dateNaissance){
      super(prenom, nom, dateNaissance); // On appelle la classe parent
   }
}

On va quand même rajouter l'attribut qui différencie l'un de l'autre:

[== Java ==]
public class Homme extends Personnage
{
   private String sexe = "masculin";
  
   public Homme (String prenom, String nom, Date dateNaissance){
      super(prenom, nom, dateNaissance); // On appelle la classe parent. Ici Personnage
   }
}

Enfin, pour tester que nos classes fonctionnent correctement, on va aussi rajouter un getter sur le sexe afin de pouvoir l'afficher.

[== Java ==]
...
public String getSexe()
{
  return this.sexe;
}
...

Ce qui nous donnerait actuellement les codes suivant:

Homme:

[== Java ==]
public class Homme extends Personnage
{
   private String sexe = "masculin";
  
   public Homme (String prenom, String nom, Date dateNaissance){
      super(prenom, nom, dateNaissance); // On appelle la classe parent
   }

   public String getSexe()
   {
      return this.sexe;
   }
}

Femme:

[== Java ==]
public class Femme extends Personnage
{
   private String sexe = "féminin";
  
   public Femme (String prenom, String nom, Date dateNaissance){
      super(prenom, nom, dateNaissance); // On appelle la classe parent
   }

   public String getSexe()
   {
      return this.sexe;
   }
}

A ce stade nos deux classes sont créées mais il restera encore une chose a faire pour avoir accès aux attributs du parent, depuis leur enfant (celles-ci étant privées).

Vous vous souvenez des visibilités public et private ? Et bien il en existe une autre qui est protected, dont l'usage sert justement à n'ouvrir l'accès qu'aux classes enfants.

Ainsi, en déclarant protected les attributs de Personnage, actuellement en private, on pourra y accéder depuis Homme et Femme.

[== Java ==]
public class Personnage
{
   protected String prenom; // private -> protected
   protected String nom; // private -> protected
   protected Date dateNaissance; // private -> protected

   ...
}

Petite remarque par rapport à ces deux classes: créer des classes Homme et Femme n'est absolument pas nécessaire, il était plus simple de juste ajouter un attribut sexe à la classe Personnage et le tour était joué. Ces deux classes sont construites à des fins pédagogiques uniquement, afin d'expliquer le fonctionnement par un exemple que j'espère le plus parlant possible. De la même manière on pourrait créer des classes Enfant, Adulte, Vieux ou quelque chose de plus parlant comme Utilisateur, Modérateur et Administrateur. Tous sont des Personnage (avec un prénom, un nom, ..., auquel on peut encore rajouter des attributs), la différence étant des fonctionnalités en plus.

3.Le polymorphisme

Le polymorphisme va permettre de varier le comportement d'une entité a travers ses enfants. C'est un peu vague dit comme ca, mais imaginons:

[== Java ==]
Personnage perso1 = new Homme("Linus","Torvalds",28-12-1969);
Personnage perso2 = new Femme("Marie","Curie",07-11-1867);

perso1 et perso2 sont des entités Personnage, pourtant on ne les a pas construit avec new Personnage(prenom, nom, date). Homme et Femme étant des descendants de Personnage, il est possible de créer directement l'objet Personnage (on va voir comment). Pareillement lorsqu'on passera un objet de type <Personnage> a une méthode, on pourra envoyer un objet Homme ou Femme, voir un new Homme(prenom, nom, date) directement.

exemple :

[== Java ==]
...
public String afficherInfoPersonnage(Personnage perso)
{
  return "prénom:"+perso.getPrenom()+" nom:"+perso.getNom()+" age:"+String.valueOf(perso.getAge());
}
...
System.out.println("Les infos de mon personnage: "+afficherInfoPersonnage(new Homme("Toto","LaChance",01-01-1980)));
...

Pour parvenir a ce résultat, on va d'abord en venir à la notion de surcharge (override en anglais, d'où les @Override ou overrideable qu'on pourrait retrouver plus tard)

La surcharge:

(a venir...)


Avant de poser vos questions, jeter un oeil ici
Mon CodeVault et Wiki : ici
Les messages privés envers le staff sont uniquement pour les cas d'urgence ou affaires privées (personnelles). Les demandes se feront exclusivement sur le forum. Merci de respecter cette clause sous peine de sanctions.

Hors ligne

Pied de page des forums