Download - La programmation orientée objet
Historique • 1990 :
Internet peu connu, Web inexistant, Projet Oak de SUN Microsystems Langage pour la communication des appareils électroniques de poche et domotique
• 1993 :
Le NCSA (National Center for Supercomputing Applications) lance MOSAIC premier navigateur internet (protocole http, langage html)
Oak s’adapte à la technologie internet
• 1995 : Annonce officielle de la naissance de la technologie Java (issue de Oak)
Technologie Java - 1
• Langage de programmation orienté objet
• Machine virtuelle (JVM) Java Virtual Machine
• Bibliothèques de classes standards
(API) Application Programming Interface
(> 2500 classes dans java 1.4)
http://java.sun.com/j2se/1.4.2/docs/api/
• Ensemble d’outils (java, javac, javadoc, jar…)
Technologie Java - 2
interpréteur
Programme
Données
compilateur Fichier
exécutable Programme
Données
(Rappels)
Technologie Java - 3
compilateur
Fichier
« class »
Programme
« java »
Données
« interpréteur »
Machine Virtuelle Java Hello.java
Hello.class
byte-code
La machine virtuelle
Réseau
ou
système
de fichiers
Class loader
Byte-code verifier Interpreter
Security manager Classes
locales
JVM
Approche orientée objet
• Logiciel = Collection d'objets dissociés définis
par des propriétés
Propriétés :
- Attributs
description de l'état de l'objet
- Méthodes
description du comportement de l'objet
Qu’est-ce qu’un objet ?
• Objet = concept, abstraction, entité …
sémantique propre au contexte
Exemple :
Deux éléphants ont le même âge, la même
taille, le même poids !!!
Mais sont 2 objets distincts
Qu’est-ce qu’une classe ?
• Une classe regroupe des définitions
d’attributs et de méthodes : c’est une
catégorie particulière d'objets.
• Un objet est une instance de sa catégorie
de référence.
Exemple : la classe Personne a comme
instances eric, maina, ... et ali qui sont
des objets distincts.
Qu’est-ce qu’une méthode ?
• Une méthode est une fonction ou une
procédure attachée à une classe.
• Une méthode peut agir sur tous les objets de
la classe sans distinction (STATIC)
méthode de classe
• ou bien n'agir que sur un objet bien particulier
(non STATIC) méthode d’objet
Exemple
ATTRIBUTS
(les variables)
METHODES
(les fonctions)
Portion invisible de
l'extérieur
private
Portion visible de
tous les autres
public
Exécution : Échanges de messages entre objets
• Les objets interagissent en s'envoyant des messages
• Un message est formé : 1 - d'un objet destinataire du message 2 - du nom d'une méthode, point d'entrée sur l'objet destinataire 3 - d'arguments à associer aux paramètres de la méthode appelée
nom_objet.nom_méthode(arg1, arg2, …);
Exemple
int x
float y
char c
… // Les attributs
m1() m2()
m3()
m4()
m5() m6()
…
m7()
int x
float y
char c
… // Les attributs
m1() m2()
m3()
m4()
m5() m6()
…
m7()
messages
Objet2 Objet1
méthodes méthodes
Création d’objets : Constructeurs
• Constructeur(s) d'objet : méthode(s)
particulière(s) ayant le même nom que la classe : Appel d’un constructeur : on peut voir cela comme un message
envoyé au gestionnaire de tous les objets existants.
• Un objet peut avoir à créer un autre objet :
Nom_classe var_objet ; //référence
var_objet = new Nom_classe(arguments… );
Premier objet ...
public class Essai1 {
public static void main( String [] args ) {
System.out.println("Bonjour") ;
}
}
Point d’entrée
Premier objet ...
import javax.swing.*; // librairie graphique
public class Essai1 {
public static void main( String [] args ) {
JFrame f1 = new JFrame("Premiers objets...(1)");
JFrame f2 = new JFrame("Premiers objets...(2)");
f1.setSize(300, 300);
f2.setSize(300, 300);
f1.setVisible(true); // pareil que f1.show();
f2.setVisible(true);
}
}
Point d’entrée
f1.show();
Méthode déconseillée (depricated) :
C’est une méthodes qu’il ne faut pas utiliser
Il existe un autre moyen pour faire la même chose
Héritage de classe • Il est possible (et souhaitable) de réutiliser une
classe existante pour créer une sous-classe plus spécifique
• La sous-classe :
– dispose des mêmes attributs et méthodes que la classe parente dont elle hérite
– peut avoir des attributs et méthodes supplémentaires, spécifiques
– peut aussi redéfinir des éléments hérités, afin d'adapter une fonctionnalité générale à ses spécificités
Premiers objets hérités
import javax.swing.*;
public class MesFenetres extends JFrame {
public static int nbre=1;
public MesFenetres() {
System.out.println("Premiers objets... "+nbre);
nbre++;
setSize(300,300);
setBackground(new Color(0,255,0));
setVisible(true) ;
}
}
Premiers objets hérités
// Test
public class Essai2 {
public static void main( String args[ ] ) {
MesFenetres f1 = new MesFenetres();
MesFenetres f2 = new MesFenetres();
}
}
Pourquoi faire
de la programmation objet ?
• Pour certaines applications, la programmation
structurée devient trop compliquée et trop
« linéaire »
• On déroule des sous-programmes dans un ordre
pré-établi a priori
Exemple : une application graphique multifenêtres
Application multifenêtres
• Cahier des charges : – Fenêtres dont la taille et la position sont fixées lors de
leur création
– Un curseur mobile : une petite croix
– Commandes reliées à l'utilisation d'un périphérique (clavier, souris, ...) :
• Déplacer curseur (4 directions)
• Créer fenêtre (deux coins opposés fixés successivement avec le curseur)
• « PopUp » de fenêtres
Multifenêtres
(programmation structurée)
struct fenetre { int xsg, ysg; //coin supérieur gauche
int xid, yid; //coin inférieur droit
struct bitmap zone; //zone recouverte
};
struct listf { struct fenetre F;
struct listf *suivante ; }; //liste de fenêtres
struct pile_file_f { struct listf *debut, *fin; };
//pile ou file des fenêtres selon opération
struct curseur { int cx,cy ; }; //position courante
Multifenêtres
(programmation structurée)
• Déplacer le curseur : modification des valeurs cx et/ou cy
• Création de fenêtre :
- créer une structure fenêtre supplémentaire
- y placer les valeurs de xsg, ysg, xid, yid et la zone d'écran recouverte - empiler la nouvelle structure fenêtre ( premier plan : sommet de pile_file_f ) - afficher la nouvelle fenêtre
Multifenêtres
(programmation structurée)
struct pile_file_f PFF; //global, fenêtres actives
PopUP : {
Trouvée=FAUX;
liste = PFF->debut;
répéter {
si (contient_position(liste->F,cx,cy) alors Trouvée=VRAI;
sinon liste = liste->suivante; }
jusqu'à (Trouvée OU vide(liste));
si (Trouvée) alors { //fenêtre sous curseur
si (liste == PFF->debut) alors {
si (PFF->debut != PFF->fin) alors {
enfiler(liste,PFF); // dernier plan
dépiler(PFF); } }
sinon {
empiler(liste,PFF); // premier plan
enlever (liste, second(PFF)); // ôter du second plan }
}
Des solutions ?
• La fenêtre déplacée doit communiquer sa
« zone couverte » à toutes les fenêtres qui se
trouve devant elle
– Comme si la fenêtre déplacée avait disparu
• On re-dispose tout à l’écran en partant d’un
fond uni et en replaçant les fenêtres dans
l’ordre, de l’arrière-plan à l’avant-plan
Problèmes
de la programmation structurée
• Une légère modification des spécifications oblige
à reprendre l'ensemble du logiciel et à re-vérifier
que tout fonctionne
• Quelques exemples d’améliorations :
- pouvoir détruire une fenêtre
- déplacer une fenêtre
- mettre une fenêtre sous forme d'icône
C'est encore plus gênant quand ce n'est pas la
même personne qui fait des modifications !
Les interfaces • C’est un modèle d'implémentation
public interface I_GestionDuSon {
public void reglerVolume( int valeur ) ;
public int volume() ;
…
}
(Toutes les interfaces portent implicitement le modificateur abstract)
• implements permet d'indiquer que la classe fournit une implémentation pour une ou plusieurs interfaces
public class Magnetophone implements I_GestionDuSon {
public void reglerVolume( int valeur ) {
… // description du comportement
}
…
}
Les interfaces
• Lorsque des objets fonctionnent bien et ont été testés d’autres programmeurs peuvent les utiliser :
1 - Appels des méthodes de ces objets 2 - Héritage à partir d’objets existants 3 - Raccordement d’un objet créé par l’utilisateur à un objet existant par des interfaces
Exemple : la gestion d’événements.
Gestionnaire d’événements - 1
import java.awt.*;
import java.awt.event.*;
public class Controleur implements WindowListener {
public void windowOpened (WindowEvent e)
{ System.out.println(e.toString()); }
public void windowClosing (WindowEvent e)
{ System.out.println(e.toString()); }
public void windowClosed (WindowEvent e)
{ System.out.println(e.toString()); }
public void windowIconified (WindowEvent e)
{ System.out.println(e.toString()); }
public void windowDeiconified (WindowEvent e)
{ System.out.println(e.toString()); }
public void windowActivated (WindowEvent e)
{ System.out.println(e.toString()); }
public void windowDeactivated (WindowEvent e)
{ System.out.println(e.toString()); }
}
Gestionnaire d’événements - 2
public class MesFenetres extends JFrame {
public static int nbre=1;
public MesFenetres(Controleur c) {
System.out.println("Premiers objets... "+nbre);
nbre++;
addWindowListener(c);
setSize(300,300);
setBackground(new Color(0,255,0));
setVisible(true);
}
}
Gestionnaire d’événements - 3
public class Essai3 {
public static void main( String [] args) {
Controleur co = new Controleur();
MesFenetres f1 = new MesFenetres(co);
MesFenetres f2 = new MesFenetres(co);
}
}
Auto-référence - 1
• Le mot clé this permet :
– de faire référence à l’objet courant (celui que l’on est
en train de définir),
– ou de désigner ses attributs, ses méthodes ou
ses constructeurs :
this.nomAttribut
this.nomMethode()
this(Arguments, …) // un constructeur
Auto-référence - 2
• Le mot clé super permet :
– de faire référence à l’objet de la super-classe dont
hérite l’objet courant,
– ou de désigner les attributs, les méthodes ou
les constructeurs de la super-classe :
super.nomAttribut
super.nomMethode()
super(Arguments, …) // un constructeur
Auto-référence - 3 public class MesMenetres extends JFrame implements WindowListener {
public static int nbre=1;
public MesFenetres() {
super("Premiers objets...(" + nbre + ")");
nbre++;
this.addWindowListener(this);
this.setSize(300,300);
this.setBackground(new Color(0,255,0));
this.setVisible(true);
}
public void windowOpened (WindowEvent e) { }
public void windowClosing (WindowEvent e) {
System.exit(0) ;
}
public void windowClosed (WindowEvent e) { }
public void windowIconified (WindowEvent e) { }
public void windowDeiconified (WindowEvent e) { }
public void windowActivated (WindowEvent e) { }
public void windowDeactivated (WindowEvent e) { }
}
Auto-référence - 4
…
public void windowOpened (WindowEvent e) { }
public void windowClosing (WindowEvent e)
{ System.exit(0); }
public void windowClosed (WindowEvent e) { }
public void windowIconified (WindowEvent e) { }
public void windowDeiconified (WindowEvent e) { }
public void windowActivated (WindowEvent e) { }
public void windowDeactivated (WindowEvent e) { }
}
Le polymorphisme
• Un même nom de méthode peut être utilisé pour des usages différents
C’est l’objet manipulé qui va en déterminer la fonction
Exemple : signification de + ? Addition d’entiers, de réels, "a"+"bc", bleu+vert
• Les paramètres sont des références à des objets (comme des pointeurs en C)
On peut avoir en argument des objets très différents et leur appliquer une méthode de nom identique
Polymorphisme ad hoc
• Possibilité d'avoir des méthodes de même nom
dans des classes sans aucun rapport entre elles
public class Armoire {
public void remplir( ) {
… // traitement spécifique à l’armoire
}
}
public class Bouteille {
public void remplir( ) {
… // traitement spécifique à la bouteille
}
}
Polymorphisme d’héritage
• Possibilité de redéfinir une méthode dans des
classes héritant d'une classe de base
public abstract class Piece {
public abstract void deplacer();
}
public class Cavalier extends Piece {
public void deplacer( ) {
… // traitement spécifique au cavalier
}
}
public class Reine extends Piece {
public void deplacer( ) {
… // traitement spécifique à la reine
}
}
Polymorphisme paramétrique
• Possibilité de définir plusieurs fonctions de même nom mais possédant des paramètres différents (en nombre et/ou en type)
public class Voiture {
public float faire_le_plein() {
… // traitement
return(prix);
}
public void faire_le_plein( int jauge, Carburant c ) {
… // traitement
}
public void faire_le_plein( float kms, Carburant c ) {
… // traitement
}
}
Les « packages »
Package : regroupement de classes ayant un
lien logique entre elles
– pour les utiliser dans d'autres classes
– pour les « spécialiser »
En plus d’un langage de programmation,
l’environnement Java définit une API (Application
Programmer’s Interface) comportant de nombreux
« packages »
(ou paquetage)
API
Principaux packages - 1
java.lang : classes essentielles
objet, types de base, processus
java.util : structures de données (collections)
listes, ensembles, hashtables, arbres, itérateurs …
java.awt: interface graphique (Abstract Window Toolkit)
fenêtres, boutons, événements ...
java.io : entrées / sorties
flot de données provenant : d'un fichier, d'un buffer, d'un "pipe »
java.net : réseau
URL, sockets
API
Principaux packages - 2
java.rmi : objets distribués (Remote Method Invocation)
java.sql : JDBC (Java Data Base Connectivity)
connexion à une base de données relationnelle
envoi de requêtes SQL, récupération des résultats
java.beans : composants logiciels
composants logiciels autonomes pouvant être contrôlés dynamiquement
et assemblées pour former des applications
modèles de composants de SUN
environnement d'exécution des JavaBeans intégré dans la plate-forme
Java
javax.swings : interface graphique
composants d’interface de plus haut niveau que ceux de awt
look and feel indépendant de l ’OS (Operating System)
exploitation du modèle MVC (Model View Controler )
Le JDK
JDK Java Developer’s Kit : environnement
standard (Windows, Solaris ou linux) diffusé
gratuitement par Sun : http://java.sun.com
– outils de développement : compilateur,debugger, …
– "librairies" de classes standards
– documentation
Version actuelle Java 1.6
Version 1.7 (en cours ?)
Le JDK 1.7
• Ajout de type String dans la commande switch
• Automatisation de certains accès aux ressources
– Fermeture automatique des fichiers ouverts
• Ajout de certaines initialisations aux collections
– List<String> list = ["item"];
• Les underscores (entiers et binaires) :
– int billion = 1_000_000_000;
– int binary = 0b1001_1001;
• Amélioration des performances
Les applets
• Hériter de la classe Applet de Java
• Définir les méthodes :
- init : réservation des ressources, initialisation
- start : première activation
- stop : arrêt dès que la page de l’applet
n’est plus vue
(reprise d’activité dès qu’on la revoit )
- destroy : libération des ressources, fin
Les applets import java.awt.*;
import java.awt.event.*;
import java.applet.*;
public class essai6 extends Applet {
outils6 mesoutils;
TextArea messages;
public void init() {
messages=new TextArea("Hello!",2,40);
setLayout(new BorderLayout());
add("North",mesoutils=new outils6(messages));
add("Center",messages);
messages.append(" init fini! ");
}
public void destroy() {
remove(mesoutils);
remove(messages);
}
public void start() {
messages.append(" start fait! ");
}
Les applets
public void stop() {
messages.append(" applet stoppee! ");
}
public static void main( String args[ ] ) {
Frame f= new Frame("applet");
essai6 monapplet = new essai6();
monapplet.init();
monapplet.start();
f.add(monapplet);
f.setSize(300,300);
f.setBackground(new Color(0,0,255));
f.show();
}
}
class outils6 extends Panel implements ActionListener {
TextField e;
TextArea ptrmessages;
Les applets
outils6(TextArea ta) {
Button b = null;
ptrmessages=ta;
add(e = new TextField("45", 4));
b = new Button("Dessin");
b.addActionListener(this);
add(b);
b = new Button("Reset");
b.addActionListener(this);
add(b);
}
public void actionPerformed(ActionEvent ev) {
String label = ev.getActionCommand();
System.out.println(ev.toString());
System.out.println(label + " " + e.getText().trim());
ptrmessages.append(" "+label + " " + e.getText().trim());
}
}
…
…
<applet height=100 width=100
codebase="myclasses/"
code="My.class">
<param name="ticker">
</applet>
…
…
Ma_page.html
Du Java sur le web
Une applet toute simple import java.awt.*;
import java.applet.*;
public class essai7 extends Applet {
TextArea messages;
public void init() {
messages=new TextArea("Hello!",2,40);
add("Center",messages);
messages.append(" init fini! ");
}
public void destroy() {
remove(messages);
}
public void start() {
messages.append(" start fait! ");
}
public void stop() {
messages.append(" applet stoppee! ");
}
}
Thread = Tâche
Thread monProcess = new Thread();
Modification des propriétés
monProcess.setPriority(MAX_PRIORITY);
Démarrage
monProcess.start();
Appel de la méthode run() de monProcess
Définition de la méthode run() Spécialisation de run() dans une sous-classe de Thread
Implémentation de l’interface Runnable
Les Threads
Synchronisation (verrou)
sur un objet Exemple : public class Bouteille {
private double volume;
public Bouteille() {
volume = 0;
}
public synchronized double niveau() {
return volume;
}
public synchronized void remplir(double quantite) {
volume = volume + quantite;
}
}
niveau et remplir sont exécutés en exclusion mutuelle
Synchronisation
Bloquer une tâche wait();
sur un objet quelconque
Réveiller d’une tâche notify();
sur l’objet cause du blocage
Réveiller toutes les tâches notifyAll();
sur l’objet cause du blocage
Passer en état d'attente sleep(delai); // en millisecondes
Génère une InterruptedException
Redonner le contrôle au scheduler yield();
Attendre
try {
wait(delai); // en millisecondes }
catch (InterruptedException e) {
// Actions à faire si le délai est dépassé
}
Les Threads : exemple
import java.awt.Graphics;
import java.awt.Color;
import java.util.*;
import java.text.DateFormat;
public class Clock extends java.applet.Applet implements Runnable {
private Thread clockThread = null;
public void init() {
setBackground(Color.white);
}
public void start() {
if (clockThread == null) {
clockThread = new Thread(this, "Clock");
clockThread.start();
}
}
Les Threads : exemple public void run() {
Thread myThread = Thread.currentThread();
while (clockThread == myThread) {
repaint();
try {
Thread.sleep(1000);
}
catch (InterruptedException e) { }
}
}
public void paint(Graphics g) {
Calendar cal = Calendar.getInstance();
Date date = cal.getTime();
DateFormat dateFormatter = DateFormat.getTimeInstance();
g.drawString(dateFormatter.format(date), 5, 10);
}
public void stop() {
clockThread = null;
}
}