Marin, capable de modéliser des marins. Pour le moment, cette classe va rester simple : un marin possède un nom et un prénom, deux chaînes de caractères, ainsi qu'un salaire, entier. Écrivons cette classe de la façon la plus simple possible, nous verrons dans la suite qu'elle comporte des erreurs de conception, mais cela reste un premier exemple accessible.
Exemple 2. Une première version de la classe
Marin
public class Marin {
String nom, prenom ;
int salaire ;
public Marin (String nouveauNom, String nouveauPrenom, int nouveauSalaire) {
nom = nouveauNom ;
prenom = nouveauPrenom ;
salaire = nouveauSalaire ;
}
public Marin (String nouveauNom, int nouveauSalaire) {
nom = nouveauNom ;
prenom = "" ;
salaire = nouveauSalaire ;
}
public void augmenteSalaire (int montant) {
salaire = salaire + montant ;
}
}
public class Marin
nom et
prenom de type
String, et
salaire de type
int
public Marin (il y en a deux), et
public void augmenteSalaire.
public void augmenteSalaire est une méthode classique. Le mot-clé
public signifie qu’elle peut être appelée en dehors de la classe. L’identificateur
void indique que cette méthode ne renvoie rien. Le mot
augmenteSalaire est le nom de la méthode.
Suit une parenthèse qui désigne les arguments que l’on doit passer à cette méthode, un entier de type
int dans ce cas.
Le nom d’une méthode et les paramètres qu’elle reçoit constituent ici la signature d’une méthode. Deux méthodes sont différentes si leurs signatures sont différentes. Elles peuvent donc avoir le même nom, à condition qu'elles diffèrent par les paramètres qu’il faut leur passer, et qu'elles aient même type de retour. Nous verrons d'autres contraintes sur les méthodes dans la suite.
Les deux premières méthodes
public Marin sont d'un type particulier : elles ne possèdent pas de type de retour. Ces méthodes sont les constructeurs de la classe
Marin. Nous verrons en détails la fonction des constructeurs en Java, et leur fonctionnement interne, disons pour le moment que pour obtenir un objet instance d'une classe, il faut appeler explicitement l'un de ses constructeurs (ici nous en avons écrit deux), avec les bons paramètres.
Un constructeur est une méthode qui doit respecter quelques contraintes :
void),
public.
Marin marin1 = new Marin ("Surcouf", "Robert", 25000) ;
L’utilisation de
new réserve un espace mémoire capable de contenir un objet de type
Marin, et l'initialise. Nous reverrons en détail en quoi consiste cette initialisation, disons pour le moment qu'il s'agit de mettre à 0 le contenu de cet espace mémoire. Un appel est ensuite fait au constructeur qui a pour signature
Marin (String, String, int). Cet espace mémoire est enfin référencé par
marin1.
Créons un autre objet de type
Marin de cette façon :
Marin marin2 = marin1 ;Lorsque l’on utilise une affectation d’objet, la machine Java recopie la référence vers l’objet cible dans la variable de destination. Donc l’objet
marin2 référence la même zone mémoire que
marin1. Il n’y a pas, dans les opérateurs d’affectation d’objet, de duplication de la zone mémoire. Les deux objets
marin1 et
marin2 sont donc les mêmes.
Testons cela sur quelques exemples simples. Augmentons le salaire de
marin1 par appel de la méthode
augmenteSalaire(int) :
marin1.augmenteSalaire(100) ;Le salaire de
marin2 est aussi augmenté, puisqu’il s’agit physiquement du même objet.
Programmons la commande :
marin1.nom = marin1.nom.toUpperCase() ;On convertit de ce fait le champ nom de
marin1 en majuscule. Comme
marin2 partage ce champ avec
marin1,
marin2.nom est aussi en majuscules. Comparons
marin1 et
marin2 :
boolean b1 = (marin1 == marin2) ;Lorsqu'il agit sur des objets, l'opérateur d'égalité
== compare les valeurs des références, et non pas leur contenu. Si les deux références
marin1 et
marin2 référencent la même zone mémoire (en C on aurait parlé de pointeurs, et d'adresses), alors elles sont égales. Dans ce cas, la valeur de
b1 est
true.
Instancions maintenant
marin1 et
marin2 de la façon suivante :
Marin marin1 = new Marin ("Surcouf", "Robert", 25000) ;
Marin marin2 = new Marin ("Surcouf", "Robert", 25000) ;
Cette fois-ci, dans la mesure où chaque variable porte une référence vers une zone mémoire qui lui est propre (deux opérations new sont réalisées), changer un champ de
marin1 n'aura pas d'effet sur
marin2.
Comparons
marin1 et
marin2 de la même façon que précédemment :
boolean b2 = (marin1 == marin2) ;La valeur de
b2 est dans ce cas
false, puisque les deux objets
marin1 et
marin2 sont logés dans deux zones mémoire différentes.
String
StringBuffer et
StringBuilder