POO - Freecyranac.free.fr/pub/cours/cnamCDL/CDL/Supports/Cours/J3_JavaOOII.pdfau top-level, comme...

Post on 12-Jul-2020

1 views 0 download

Transcript of POO - Freecyranac.free.fr/pub/cours/cnamCDL/CDL/Supports/Cours/J3_JavaOOII.pdfau top-level, comme...

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 !)