Post on 12-Jul-2020
POO
Programmation Impérative
Programmation orientée Objet et modélisation UML
Aspects Objets avancés dans le langage Java
Collections
Concepts Objet Avancés
Apis
Exception
classes abstraites
Interface
observateur
Clonage
Structures de données récursives
Classes internes,
classes anonymes
Types int.class classe Class
Patterns, évènements
APIs
APIs
Chap VI: ExceptionsObject
(from java.lang)
Throwable
Throwable () : voidThrowable (message : String) : voidtoString () : StringprintStackTrace () : voidgetMessage () : StringprintStackTrace0 (s : Object) : voidfillInStackTrace () : ThrowablegetLocalizedMessage () : StringprintStackTrace (s : java.io.PrintStream) : void
Exception
Exception () : voidException (s : String) :
Error
Error () : voidError (s : String) : void
LinkageError(from java.lang)
ThreadDeath(from java.lang)
VirtualMachineError(from java.lang)
java.lang
Sous classes ExceptionException
Exception () : voidException (s : String) : void
RuntimeException(from java.lang)
ClassCastException(from java.lang)
IndexOutOfBoundsException(from java.lang)
ArrayIndexOutOfBoundsException(from java.lang)
StringIndexOutOfBoundsException(from java.lang)
NullPointerException(from java.lang)
IllegalArgumentException(from java.lang)
ClassNotFoundException(from java.lang)
CloneNotSupportedException(from java.lang)
NoSuchFieldException(from java.lang)
NumberFormatException(from java.lang)
CommentairesQuand une exception est levée, les expressions, instructions,méthodes, constructeurs, initialisateurs statiques qui subissent cetteexception sont interrompus abruptement jusqu'à ce qu'unedéclaration intercepte cette classe d'exception (ou une superclassede celle ci). Si l'exception n'est pas interceptée la JVM appelle laméthode uncaughtException sur le ThreadGroup. au fur et àmesure les verrous sont libérés.
Error et RunTimeException ne sont pas nécessairement "catchées"
soit que cela serait trop lourd soit parfois trop difficile
Si on écrit ...} catch(Exception e){..} on récupère donc toutes lesexceptions sauf Error.
Classes Exception
class PilePleineException extends Exception{
PilePleineException(){}
PilePleineException(String s){super(s);}}
class PileVideException extends Exception{
}
Exception et Pileclass Pile{ private int[] table; private int sommet =-1;
public Pile(int taille){table =new int[taille];
} public void empiler(int v) throws PilePleineException {
try{ table[++sommet]=v;} catch(ArrayIndexOutOfBoundsException e){ throw new PilePleineException(Integer.toString(sommet));}
} public int depiler()throws PileVideException{
try{return table[sommet--];}catch(ArrayIndexOutOfBoundsException e){throw new PileVideException();}
}
public boolean estVide(){... } public boolean estPleine(){... } public String toString(){... }}
Structures de DonnéesRécursives
•Application au même exemple de pile•Structure de donnée générique•Généricité, spécialisation et héritage
Exercice: Pile de taille libre
modélisation objet d’une pile de taille «illimitée»
Pour les connaisseurs l’objectif de cet exercice est demontrer comment java et l’approche objet se passentaisément de la notion de pointeur habituellementintroduite pour la solution de cet exercice.
valeur 2Maillon sousPile
:Maillon:Maillon
sousPilevaleur 8Maillon sousPile
taille 2Maillon sommet
:Pilesommet
Pile d’entier de taille libre
sousPile
sommet
Maillonint valeur
toString( )sousPile
Pileint tailleMaillon sommet
estVide( )depiler( )empiler( )toString( )
Maillon
class Maillon{ int valeur;
Maillon sousPile; Maillon(int valeur,Maillon sousPile){
this.valeur=valeur;
this.sousPile=sousPile; }
public String toString(){return valeur + ((sousPile!=null)? ", "+ sousPile : "");
}}
Pile de taille libreclass Pile{ private int taille =0; private Maillon sommet; public void empiler(int v){
sommet=new Maillon(v,sommet);taille++;
} public int depiler(){
int v=sommet.valeur; sommet=sommet.sousPile;
taille--;return v;
} public boolean estVide(){
return taille==0; } public String toString(){
return "[ "+ sommet.toString() +" ]"; }}
Généricité et Classe Object
On veut maintenant généraliser notre pile pour qu’elle puisseservir de pile d’objets et non plus seulement de pile d’entiers.
Maillon d’objets
class Maillon{ Object valeur; Maillon sousPile; Maillon(Object valeur){
this.valeur=valeur; } public String toString(){
return valeur + ((sousPile!=null)? ", "+ sousPile : ""); }}
Pile d’Objetsclass Pile{ int taille =0; Maillon sommet;
public void empiler(Object v){Maillon nouveauSommet=new Maillon(v);nouveauSommet.sousPile=sommet;sommet=nouveauSommet;taille++;
} public Object depiler(){
Object v=sommet.valeur; sommet=sommet.sousPile;
taille--;return v;
} public boolean estVide(){
return taille==0; } public String toString(){
return "[ "+ sommet.toString() +" ]"; }}
Empiler les chainespublic class PileChaine {
public static void main(String[] args){Pile pile= new Pile();int i=0;while(i<args.length){
pile.empiler(args[i]); // on empile un objet String System.out.println(i+": "+ args[i]); // polymorphisme i++;}i=0;while(i<args.length){ System.out.println(i+": "+ pile.depiler()); //polymorphisme i++;}
}}
Wrappers des types de base
Double(from java.lang)
FloatIntegerint value; int MIN_VALUE ;int MAX_VALUE;
Integer (value : int) : voidintValue () : intInteger (s : String) : voidparseInt (s : String) : inttoString () : StringvalueOf (s : String) : Integer
Boolean$ TRUE : Boolean$ FALSE : Boolean
Boolean (value : boolean) : voidbooleanValue () : booleantoString () : String
Character
Character (value : char) : voidcharValue () : charisLowerCase (ch : char) : booleantoString () : String
Number
Object(from java.lang)
Sous-classe:généricité et polymorphisme
public class PileChaine {
public static void main(String[] args){Pile pile= new Pile();int i=0;while(i<args.length){ pile.empiler(args[i]); // on empile un objet String System.out.println(i+": "+ args[i]); i++;}pile.empiler(new Integer(3)); // on empile un objet Integerpile.empiler(new Float(3.0));i=0;while(!pile.estVide()){ System.out.println(i+": "+ pile.depiler().toString()); //polymorphisme i++;}
}}
Sous Classehéritage et surcharge
class PileString extends Pile{ public void empiler(String s){
super.empiler(s); } public void empiler(Object v){
if(v instanceof String) super.empiler(v);else System.out.println("c'est une pile de String et non de "+v.getClass());
} public Object depiler(){ // deux méthodes ne peuvent différer par le seul type de retour
return (String)super.depiler(); }}
Autre exemple
class PileInt extends Pile{ public void empiler(int i){ // surcharge
super.empiler(new Integer(i)); } public void empiler(Object v){
if(v instanceof Integer) super.empiler(v);else System.out.println("c'est une pile d'Integer et non de "+v.getClass());
} public int depilerInt(){ // deux méthodes ne peuvent différer par le seul type de retour
Integer i=(Integer)super.depiler();return i.intValue();
}}
Pile Générique et héritage
sousPile
Piletaille : int
estVide () : booleandepiler () : Objectempiler (v : Object)toString () : String
Maillonvaleur : Object
toString () : StringMaillon (valeur : Object, sousPile : Maillon) :
#sommet
ExemplePileChaine
main (args : String[])
PileString
empiler (s : String)depilerString () : Stringempiler (v : Object)
pile
PileInt
empiler (i : int)depilerInt () : intempiler (v : Object)
Classes Abstraiteset
Interface
Classe Abstraitepublic class PileAbstraite { public static void main(String[] args){
Pile pile= new PileString(); // la classe est abstraite mais l'instance non...
}}class Maillon{...}
abstract class Pile{ int taille =0; abstract public void empiler(Object v); abstract public Object depiler(); public boolean estVide(){
return taille==0; }}
class PileRécursive extends Pile{ Maillon sommet; public void empiler(Object v){... } public Object depiler(){... } public String toString(){... }}
class PileString extends PileRécursive { … .}
Interface
interface Pile{ void empiler(Object v); Object depiler(); boolean estVide();}
Interface et Compilation séparée
L’interface permet en particulier de développer en appliquant lestechniques de compilation séparée.
On développe et compile une interface.interface C{
}
On développe et compile en parallèle le programme utilisateuret la ou les implémentations des interfaces.
public class CompileSeparee{
static public void main(String[] args){
C v;
System.out.println("hello");
}
}
Héritage «multiple»
abstract class C {int i;void m1( ){...}abstract String m2( );...
}
class C1 extends C implements I {String m2(){...}int[] p(){...}...
}
interface I{public final static int j=0;int[] p( );...
}
Types et Classesdans l’approche Patterns
«Un type est un nom utilisé pour caractériser une interface»
«Un objet peut avoir de nombreux types»
«Des objets différents peuvent partager un même type»
Un type hérite de l’interface de son super-type
Les interfaces sont le fondement des systèmes Orientés objets
L’implémentation des objets est définie par leur classe
La liaison dynamique permet de substituer des objets, les uns auxautres, pourvu que leur interface soit identique (polymorphisme)
itérateur java: Enumeration
public interface java.util.Enumeration{
public abstract boolean hasMoreElements(); public abstract Object nextElement();}
Java: iterateur sur un Vecteurpublic class java.util.Vector extends java.lang.Object implements java.lang.Cloneable { ... public Vector(); public Vector(int initialCapacity);
public final void addElement(Object obj); public final boolean contains(Object elem); public final Object elementAt(int index);
public final Enumeration elements();
public final Object firstElement(); public final boolean isEmpty(); public final void removeElementAt(int index); public final void setElementAt(Object obj, int index); public final int size();}
Java: itérateurs sur une Hashtablepublic class java.util.Hashtable extends java.util.Dictionary implements java.lang.Cloneable { public Hashtable();
public void clear(); public Object clone(); public boolean contains(Object value); public boolean containsKey(Object key); public Enumeration elements(); public Object get(Object key); public boolean isEmpty(); public Enumeration keys(); public Object put(Object key, Object value); public Object remove(Object key); public int size(); public String toString();}
Iterator et Enumeration Java
VectorEnumeration elements()
EnumerationnextElement();hasMoreElements();
Client
EnumerationConcrète
nextElement();hasMoreElements();
implémente>
déclare
Exempleclass Programme{
...Hashtable baseDeClauses = new Hashtable(); // ensemble indexé de paquets
public String toString(){Enumeration e= baseDeClauses.elements();String s="";while(e.hasMoreElements()){
s += ((Paquet)e.nextElement()).toString()+ rc;}return s;
}boolean existePaquet(String s){
Enumeration e = baseDeClauses.keys();
while(e.hasMoreElements())if( s==e.nextElement()) return true;
return false;}
...}
Clonage
public class Object {
public final Class getClass();
public String toString();
public boolean equals(Object obj);
protected Object clone()
throws CloneNotSupportedException;
…
}
Cloneableprotected Object clone()
throws CloneNotSupportedException;
Par défaut les objets ne sont pas clonables, cette méthode,dont tout objet hérite, teste donc d’abord si la classe du receveur implémente l’interface Cloneable
public interface Cloneable { }Si non une exception est levéeSi oui elle crée un objet du même type que le receveur et fait une copie superficielle (affectation des champs) (les tableaux implémentent cette interface)La classe Object n’implémente pas elle même cette interfaceSi vous spécialisez clone() vous pouvez faire une copie profonde en appelant cette même méthode sur les attributs « clonabes »
Exemplepublic class Stack implements Cloneable { private Vector items; … . protected Object Clone() {//pas obligé de retourner l’exception try { Stack s = (Stack)super.clone(); s.items = (Vector)items.clone(); return s; } catch (CloneNotSupportedException e) { // this shouldn't happen because Stack is Cloneable throw new InternalError(); } } }
equals
Attention à la méthode
public class Object {
…
public boolean equals(Object o);
protected Object clone() throw CloneNotSupportedException;
}
Par défaut, elle compare les pointeurs et non les contenus clonés
Classes internespeuvent apparaître partout
au top-level, comme attribut d'une classe, dans un bloc, dansune expression (anonymement)
raison d'être: 'adapter' et 'beans'
simplifie la connection d'objets entre eux
Le nom de classe interne n'est pas utilisable hors de la classe sanspréfixer.
Le code des classes internes voit directement les noms englobants.
les classes internes peuvent être déclarées 'static'. Elles sont alorstop-level comme les classes du package. L'avantage dans ce casréside dans la visibilité des attributs et dans la structuration desclasses.
Classes internesclass Pile{ int taille =0; Maillon sommet; public void empiler(Object v){... } .... public String toString(){... }
public Enumeration elements(){return new EnumerationPile();
} //------------classe interne------------------------ // a revoir
class EnumerationPile implements Enumeration{Maillon maillonCourant= sommet;
public boolean hasMoreElements(){ return maillonCourant!= null;}public Object nextElement(){ Object valeurDeRetour = maillonCourant.valeur; maillonCourant=maillonCourant.sousPile; return valeurDeRetour;}
} //---------------------------------------------------}
Classes anonymesclass Pile{
...
public Enumeration elements(){return new Enumeration(){
Maillon maillonCourant= sommet; public boolean hasMoreElements(){ return maillonCourant!= null;}public Object nextElement(){ Object valeurDeRetour = maillonCourant.valeur; maillonCourant=maillonCourant.sousPile; return valeurDeRetour;}
}; }
}
Type ou Classe
une variable à un type définit à la compilation
int, int[], PrintStream, Integer ou String
une valeur comme 3 est de type int
un objet à une classe (implémentation d'un type)
"Hello world" est de classe String.class
new int[3] est de classe int[].class
classe Class
les types primitifs sont eux aussi associés à un objet de classeClass.
cet objet est désigné par int.class par exemple pour int.
il en existe même un pour void qui pourtant n'est pas un type !!!!
On accède également à cet objet par le champ type de la classewrapper correspondante ex Integer.TYPE
Bizarre : void dispose aussi d'une classe wrapper Void (celle-ci ne peut être instanciée !)