![]() |
Le problème :
simuler par programme le calcul de π en lançant des fléchettes dans une cible inscrite dans un carré. Le rapport du nombre de flèches dans la cible sur celui des flèches dans le carré (y compris celles dans le cercle) est égal à π/4 |
Cible.java
suivant :
--> cat Cible.java
class Cible {
private int dedans;
Cible( ) {
dedans = 0;
}
int valDedans( ) {
return dedans;
}
private static double f(double x) {
// x doit être compris entre -1 et 1
return Math.sqrt(1 - x*x);
}
void lancer( ) {
// tirage d'un point dans le carré [0,1[ X [0,1[
double u = Math.random( );
double v = Math.random( );
if (v <= f(u)) dedans++;
}
}
|
Le fichier contient donc la définition d'une classe
Cible
encapsulant :
dedans (privée signifie qu'en dehors de la classe elle-même
elle n'est pas accessible directement). On parle d'une
variable d'instance :
chaque objet instanciant la classe en possédera un exemplaire.
int
qui est un des types primitifs du langage ;Cible
(c'est-à-dire de même nom que la classe)
et qui est appelée un
constructeur. Il sera utilisé pour initialiser
une instance de la classe à sa création. Ici l'initialisation
a pour effet d'affecter 0 à la variable
dedans
à la création de l'objet ;static) de nom
valDedans
et qui doit donc être invoquée via une
référence d'objet
(c'est-à-dire une expression dont la valeur est une référence
d'un objet pour lequel la fonction est connue)
qui renvoie la valeur (de type int) de la variable
dedans
de l'objet dans le contexte duquel elle est invoquée (appelée). Une telle fonction
(qu"on peut appeler un «getter» car elle permet de lire la valeur d'un champ privé d'un objet)
pallie l'impossibilité d'accéder directement à cette variable depuis l'extérieur ;static
en fait une méthode de classe :
un telle méthode est invocable indépendamment de tout
objet de la classe contrairement aux méthodes d'objets au travers du nom de la classe
méthode de classe.
f
et peut être invoquée sous la forme
Cible.f(e)
e
est une expression de type
double
(autre type primitif).
double,
est la racine carrée de
1 - x2.
sqrt: cette méthode
est une méthode de classe de la classe (Math
dans laquelle elle est définie (avec la qualification static).
lancer
qui ne retourne pas de valeur invoque deux fois la méthode statique
random
également définie dans la classe Math
qui retourne une valeur aléatoire de type
double
comprise entre 0.0 et 1.0.
u
et v
obtenues sont liées par la relation
v <= f(u),
la variable dedans
de l'objet courant est incrémentée (cette relation correspond mathématiquement au fait que le point (u,v)
atteint par la flèche est dans la cible).Simulation.java dont le contenu est :
--> cat Simulation.java
class Simulation {
private static double calculAire(int n) {
// évalue l'aire de la cible par une méthode de Monte-Carlo
Cible cible = new Cible( );
for (int i = 0; i < n; i++) cible.lancer( );
return (double)cible.valDedans( )/n;
}
public static void main(String[ ] args) {
int tirages = Integer.parseInt(args[0]);
double pi = 4 * calculAire(tirages);
System.out.println("Pi = " + pi);
}
}
|
Simulation
dont l'exécution par la machine Java va être possible
du fait de l'existence d'une méthodes main
possédant le profil (nom, liste/type des paramètres, type void du résultat) et
les attributs nécessaires (public et static).
public : la méthode a la visibilté maximale ;static : c'est une méthode de classe ;void : elle ne renvoie pas de valeur ;main : elle a le bon nom ;String [ ] args : elle a comme paramètre un tableau de chaînes de caractères.calculAire.
Cible
définie précedemment est instanciée au moyen de l'opérateur
new appliquée
au constructeur (Cible() de cette classe.
Ce constructeur porte le nom de la classe qu'il concerne.
lancer
sur l'instance de l'objet créé. A la sortie de la boucle,
on invoque la méthode valDedans
pour récupérer la valeur du champ
dedans
de ce même objet et la valeur récupérée est retournée par la fonction ;main,
on décode sous forme d'entier le premier élément du tableau
transmis à l'appel puis on appelle la méthode
statique privée calculAire
de la classe Simulation et enfin
on imprime la valeur déduite pour Pi.
Les différentes classes sont ensuite compilées en utilisant la commande
javac : l'effet de cette commande
est de produire des fichiers d'extension .class
contenant du «bytecode» et non du binaire directement exécutable
par le processeur comme c'est le cas du résultat fourni par un compilateur C par exemple.
Ces fichiers sont interpétables par la machine virtuelle Java (JVM) au travers de la commande
java.
La séquence suivante résume cette suite d'opérations:
--> javac Cible.java Simulation.java
--> ls -l Cible.class Simulation.class
-rw-r--r-- 1 rifflet users 511 sep 2 2002 Cible.class
-rw-r--r-- 1 rifflet users 893 sep 4 2002 Simulation.class
--> java Simulation
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException
at Simulation.main(Simulation.java:10)
--> java Simulation 100000
3.15172
--> java Simulation 100000
3.13956
|
La première exécution montre comment les erreurs sont signalées
en Java sous forme d' exceptions.
Ici l'exception
java.lang.ArrayIndexOutOfBoundsException, lorsqu'elle est levée,
indique que la commande a été appelée sans
paramètre et la fonction a essayé d'accéder au premier argument
(en Java comme en C les indices commencent à 0).
Les deux autres demandes d'exécution sont quant à elles correctes puisqu'elle sont réalisées en donnant
un paramètre à la commande.
Ce second exemple illustre rapidement différents aspects du langage et de manière plus générale de la programmation objets (constructeurs, héritage par définition de sous-classe, redéfinition de méthode, instanciation et liaison tardive)
--> cat Exemple2.java
class A {
int a, b;
A(int x, int y){a = x; b = y;}
void visualiser( ){
System.out.println("(" + a + "," + b +")");}
}
class B extends A{
int c;
B(int x, int y, int z){super(x, y); c = z;}
void visualiser( ){
System.out.println("(" + a + "," + b + "," + c + ")"); }
}
public class Exemple2{
public static void main(String[] arg){
A a = new A(1, 2);
B b =new B(4, 5, 6);
a.visualiser( );
b.visualiser( );
}
}
--> java Exemple2
(1,2)
(4,5,6)
-->
|