Représentés par des variables déclarée dans l'objet
Représentent un état de l'objet
Ses méthodes
fonctions auxquelles l'objet sait répondre
Représentent un comportement de l'objet
Objet Eleve durand ?
Objet Connexion uneConnexion ?
Classes
Usine de fabrication d'objets
Outil du programmeur
Permet de définir le comportement des objets
Prennent la Première lettre en majuscule
Classe Elève
Classe Connexion
Création d'un objet
Pour manipuler un objet, on déclare une référence sur la classe de cet objet :
Circle c;
Pour créer un objet, on instancie une classe en appliquant l'opérateur new sur un de ses constructeurs. Une nouvelle instance de cette classe est alors allouée en mémoire :
c = new Circle();
Constructeur
Tout objet doit avoir ses valeurs initiales positionnées. Un constructeur permet de fixer ces valeurs à la création de l'objet
Toute classe possède un constructeur par défaut, implicite. Il peut être redéfini. Une classe peut avoir plusieurs constructeurs qui diffèrent par le nombre et la nature de leurs paramètres.
Un constructeur est une méthode qui possède le même nom que la classe, mais qui ne renvoie rien
int[] array_of_int; // équivalent à : int array_of_int[];
Color rgb_cube[][][];
Création et initialisation
array_of_int = new int[42];
rgb_cube = new Color[256][256][256];
int[] primes = {1, 2, 3, 5, 7, 7+4};
array_of_int[0] = 3
Utilisation
int l = array_of_int.length;// l = 42
int e = array_of_int[50]; // Lève une ArrayIndexOutOfBoundsException
Les exceptions (1)
Elles permettent de séparer un bloc d'instructions de la gestion des erreurs pouvant survenir dans ce bloc.
Les exceptions (2)
Ce sont des instances de classes dérivant de java.lang.Exception
La levée d'une exception provoque une remontée dans l'appel des méthodes jusqu'à ce qu'un bloc catch acceptant cette exception soit trouvé. Si aucun bloc catch n'est trouvé, l'exception est capturée par l'interpréteur et le programme s'arrête.
L'appel à une méthode pouvant lever une exception doit :
soit être contenu dans un bloc try/catch
soit être situé dans une méthode propageant (throws) cette classe d'exception
Un bloc (optionnel) finally peut-être posé à la suite des catch. Son contenu est exécuté après un catch ou après un break, un continue ou un return dans le bloc try
Les exceptions (3)
Les unités de compilation
Le code source d'une classe est appelé unité de compilation.
Il est recommandé (mais pas imposé) de ne mettre qu'une classe par unité de compilation.
L'unité de compilation (le fichier) doit avoir le même nom que la classe qu'elle contient.
Les packages définition
Unité d'organisation des classes
Organisation logique : time.clock.Watch
Organisation physique : time/clock/Watch.class
Espace de nommage hiérarchique
Description de la hiérarchie : package time.clock;
Notion de nom complet : time.clock.Watch
Les bibliothèques java sont organisées en package
java.util, java.net, org.objectweb,…
Deux classes ayant le même nom complet ne peuvent pas s'exécuter en même temps.
Nom de classe : résolution
Pour résoudre un nom de classe dans une autre classe
Nom de classe : résolution
Pour résoudre le nom d'une classe soit :
On donne son nom complet lors de l'utilisation
On résout initialement son nom
On résout initialement tous les noms d'un package
Les noms des classes du package java.lang n'ont pas à être résolus
On peut donc avoir deux classes Date
java.util.Date
java.sql.Date
Les packages : organisation
Où trouver une classe ?
Les outils du système cherchent toutes les classes
Compilation et Exécution : typage fort C & E
Les classes sont recherchées sur le système de fichiers
Les classes standards sont automatiquement trouvées par les outils
Pour indiquer l'endroit sur le système de fichier à partir duquel il faut chercher les classes on utilise le classpath
Fonctionnement identique au path d'exécution
Le classpath
Il indique à partir de quel endroit recherche une classe
javac -classpath /usr/local titi.Toto.java
La classe titi.Toto est recherchée à partir du répertoire
/usr/local /*Résolution physique*/
Il faut donc que la classe soit définie dans le fichier :
La destruction des objets est prise en charge par le garbage collector (GC).
Le GC détruit les objets pour lesquels il n'existe plus de référence.
Les destructions sont asynchrones (le GC est géré dans une thread de basse priorité).
Aucune garantie n'est apportée quant à la destruction d'un objet.
Si l'objet possède la méthode finalize, celle-ci est appelée lorsque l'objet est détruit.
Destruction d'un objet
public class Circle {
...
void finalize() { System.out.println("Je suis garbage collecte"); }
...
Circle c1;
if (condition) {
Circle c2 = new Circle(); // c2 référence une nouvelle instance
c1 = c2;
}
// La référence c2 n'est plus valide mais il reste une référence,c1,
// sur l'instance
c1=null; // L'instance ne possède plus de référence. Elle n'est plus
// accessible. A tout moment le gc peut détruire l'objet.
...
}
Classes et objets
public class Circle {
protected double x, y; // Coordonnée du centre
protected double r; // rayon du cercle
public Circle(double r) {this.r = r;}
public double area() {return 3.14159 * r * r;}
public void setX(int i){this.x=i;}
public void setY(int i){this.y=i;}
}
public class MonPremierProgramme() {
public static void main(String[] args) {
Circle c; // c, référence sur un objet Circle, mais pas encore un objet
c = new Circle(5.0); // c référence maintenant un objet alloué en mémoire
c.setX(10);
c.setY(10);
System.out.println("Aire de c :" + c.area());
}
}
L'héritage
Objectifs :
Organiser les classes dans une hiérarchie de fonctionnement
Les classes présentent dans ces relations d'héritage un rapport parent / fils
La relation d'héritage représente une relation sémantique non standard entre le père et le fils
Il n'existe pas de relation d'héritage universelle entre les classes. C'est le rôle de l'architecte d'application de définir la relation qu'il sous-entend
L'héritage syntaxe
La classe parente présente généralement soit des fonctions générales à toutes les classes filles, soit des fonctions types qui doivent être (re)définie dans dans les classes filles
Héritage
La relation d'héritage indique ce que l'objet est.
Sous-type
Une sous-classe étend les capacités de sa super classe. Elle hérite des capacités de sa parente et y ajoute les siennes
De plus une sous-classe est une spécialisation de sa super-classe. Toute instance de la sous-classe est une instance de la super-classe (pas nécessairement l'inverse).
L'héritage
==> Ce qu ’une classe EST
Une classe ne peut hériter (extends) que d'une seule classe.
Les classes dérivent, par défaut, de java.lang.Object
Une référence sur une classe C peut contenir des instances de C ou des classes dérivées de C.
L'opérateur instanceOf permet de déterminer la classe d'une instance.
Les classes final ne peuvent pas être redéfinies dans les sous-classes.
super et this pour accéder aux membres d’une classe
int r = e.getRadius();// Error: method getRadius not found in class Ellipse
c = e; // Error: Incompatible type for =. Explicit cast needed.
Liaison dynamique de méthodes
Liaison dynamique des méthodes (dynamic binding of methods) : Indique que la méthode invoquée n'est choisie qu'au dernier moment (run-time), et non pas à la compilation.
Différence entre Variable/Type et Objet/Classe :
Une variable est un lieu de stockage ayant un type associé. Ce type est déterminé à la compilation. Déclaration statique.
Un objet est une instance d'une classe. Son type est déterminé quand l'objet est crée (à l'exécution).
Polymorphisme
Dans les langages statiques, il faut que la partie gauche(lhs) et droite (rhs) d'un assignement soient de types compatibles
Dans les langages objets, la partie droite droite doit être d'un sous-type de la partie gauche.
Le masquage des variables
Une classe peut définir des variables portant le même nom que celles de ses classes ancêtres.
Une classe peut accéder aux attributs redéfinis de sa classe mère en utilisant super ou par cast.
Une classe peut accéder aux méthodes redéfinies de sa classe mère en utilisant super.
Le masquage des variables
class A {
int x;
void m() {...}
}
class B extends A{
int x;
void m() {...}
}
class C extends B {
int x, a;
void m() {...}
void test() {
a = super.x; // a reçoit la valeur de la variable x de la classe B
a = super.super.x; // Syntax error
a = ((B)this).x; // a reçoit la valeur de la variable x de la classe B
a = ((A)this).x; // a reçoit la valeur de la variable x de la classe A
super.m(); // Appel à la méthode m de la classe B
super.super.m(); // Syntax error
((B)this).m(); // Appel à la méthode m de la classe C (et non B)