• Aucun résultat trouvé

super classe

N/A
N/A
Protected

Academic year: 2022

Partager "super classe "

Copied!
1
0
0

Texte intégral

(1)

Interface :

Pourquoi ?

Le Java ne supporte pas l'héritage multiple comme C++ :

super classe

A1

super classe

A2

super classe

A3 etc …

classe dérivée en C++

B

En Java une classe n'a pas le droit d'hériter directement deux super-classes. Par contre, Java permet à une classe d'être dérivée d'une seule super-classe mais implémente une ou plusieurs interfaces.

super classe en Java

A

interface I1

interface

I2 etc

sous-classe B

dérivée de A implémente I1, I2, etc

De plus, une interface contient souvent ses méthodes abstraites qui présentent certaines

comportements assez générales ( hasMoreElements() : avoir encore d’éléments,

nextElement() : prochain élément pour les structures linéaires, writeInt() : écrire un

entier, writeDouble() : écrire un réel, … pour les fichiers binaires, run() : déplacer, pour

animation, …). Ces méthodes abstraites seront réalisées dans les classes qui

implémentent cette interface.

(2)

Cas 1 de Java : StringTokenizer

classe Object

java.util

interface Enumeration

Method Summary

boolea

n hasMoreElements()

: avoir encore d’éléments

retourne true si cette énumération contient encore des elements : false sinon

Object nextElement()

: prochain élément

retourne l’élément suivant de cette énumération.

Par défaut, toutes ces méthodes sont abstraites et public.

java.util class StringTokenizer extends Object

implements java.util.Enumeration

StringTokenizer chaine = new StringTokenizer(“Java est populaire”);

while ( chaine.hasMoreElements() )

System.out.println( chaine.nexElement() );

nous donne : Java

est

populaire

(3)

Cas 2 de Java : Vector

super classe en Java AbstractList

interface

List

interface

Cloneable

interface

Serializable

public class Vector extends AbstractList

implements List, Cloneable, Serializable

(note : Vector n’implémente pas l’interface Enumeration mais une de ses méthodes retourne un objet de la « classe » Enumeration)

. . .

// cette méthode retourne une énumération des éléments de ce // vecteur

public final Enumeration elements();

. . .

Pour afficher tous les éléments d’un vecteur v :

for (Enumeration elem = v.elements() ; elem.hasMoreElements() ; )

System.out.println(elem.nextElement());

(4)

Cas 3 de Java : fichiers binaires

Java utilise le terme Reader/Writer pour désigner les suites de caractères dans le traitement des fichiers de type texte. Pour la lecture d’un fichier texte, on lit souvent ligne par ligne (avec

Entree.readLine()) et extraire des sous-chaînes de la chaîne lue puis faire la conversion en type voulu (exemple, avec Integer.parseInt(sous- chaîne)).

Contenu d’un fichier de type texte : Je suis une ligne

Je suis une autre ligne etc ….

Je suis la dernière ligne

Le Java peut détecter les caractères fin de ligne et fin de fichier.

Java utilise le terme STREAM (flux, flot) pour désigner des suites d'octets (bytes) dans le traitement des fichiers binaires :

Contenu d’un fichier binaire :

1 entier 1 réel 1 caractère 1 entier 1 réel 1 caractère etc …

writeInt() writeDouble() WriteChar() writeInt() writeDouble() WriteChar() etc … Il y a InputStream pour la lecture et OutputStream pour l'écriture.

Dans le cours IFT 1176, on traite aussi les fichiers à accès direct.

Pour localiser un fichier à écrire son contenu, Java combine 2 objets des deux classes DataOutputStream et FileOutputStream :

DataOutputStream aCreer = new DataOutputStream

( new FileOutputStream(nomFile));

On implémente et utilise des méthodes de l’interface DataOutput : public abstract void

writeInt

(int valeur);

public abstract void

writeChar

(int v);

public abstract void

writeDouble

(double val);

etc ….

pour écrire un entier, un caractère ou un réel dans le fichier binaire.

public class DataOutputStream extends FilterOutputStream implements DataOutput

Dans ce cas ci, l’interface DataOutput est un groupe de méthodes abstraites indiquant que DataOutputStream est dotée d’un comportement supplémentaire par rapport aux méthodes héritées de sa super-classe FilterOutputStream.

(5)

Les deux pages suivantes décrivent des schémas de la création et de la lecture d’un fichier binaire.

Gestion de fichiers:

Quelques classes + interfaces utilisées pour la création d'un fichier binaire :

classe Object

OutputStream

FilterOutPutStream

public void close();

FileOutputStream

public FileOutputStream String name);

etc . . .

DataOutput (une interface)

public abstract void

writeInt

(int valeur);

public abstract void

writeChar

(int v);

public abstract void

writeDouble

(double val);

etc . . .

DataOutputStream

public DataOutputStream(OutputStream os);

public final void

writeInt

(int valeur);

public final void

writeChar

(int v);

public final void

writeDouble

(double val);

etc . . .

public class java.io.DataOutputStream

extends java.io.FilterOutputStream

implements java.io.DataOutput

(6)

(DataOutputStream dérivée de FilterOutputStream implémente l'interface DataOutput)

Quelques classes + interfaces utilisées pour la lecture d'un fichier binaire :

classe Object

InputStream

FilterInputStream

public void close();

FileInputStream

public FileInputStream String name);

etc . . .

DataInput (une interface)

public abstract int

readInt

();

public abstract double

readDouble

();

etc . . .

DataInputStream

public DataInputStream(InputStream is);

public final int

readInt

();

public final double

readDouble

();

etc . . .

public class java.io.DataInputStream extends java.io.FilterInputStream implements java.io.DataInput

(DataInputStream dérivée de FilterInputStream

implémente l'interface DataInput)

(7)

/**

* Ce programme permet :

* - de créer un fichier contenant les diviseurs de 720 * - de relire le fichier et d'afficher son contenu */

import java.io.*;

public class FichierBinaire1 {

// création d'un fichier

static void creerFichier(String nomFile, int nombre) throws IOException {

DataOutputStream aCreer = new DataOutputStream

( new FileOutputStream(nomFile));

for (int candidat = 1 ; candidat <= nombre ; candidat++) if ( nombre % candidat == 0)

aCreer.writeInt(candidat);

aCreer.close();

System.out.println("Fin de la creation du fichier " + nomFile);

}

// lecture d'un fichier

static void relireFichier(String nomFile, int nombre) throws IOException {

System.out.println("Lecture du fichier binaire " + nomFile +

" contenant les diviseurs de " + nombre);

DataInputStream aLire = new DataInputStream

( new FileInputStream(nomFile));

int rang = 0 , valeur = -555 ; boolean finFichier = false ; while ( ! finFichier ) {

try {

valeur = aLire.readInt();

} catch ( EOFException e ) { finFichier = true;

}

if (!finFichier)

System.out.println(++rang + ")\t" + valeur);

}

aLire.close();

System.out.println("Fin de la lecture du fichier " + nomFile + "\n");

}

(8)

public static void main (String[] args) throws IOException {

creerFichier("C:\\DiviDe720.dta", 720);

relireFichier("C:\\DiviDe720.dta", 720);

} }

/* Exécution :

Fin de la creation du fichier C:\DiviDe720.dta

Lecture du fichier binaire C:\DiviDe720.dta contenant les diviseurs de 720

1) 1 2) 2 3) 3 4) 4 5) 5 6) 6 7) 8 8) 9 9) 10 10) 12 11) 15 12) 16 13) 18 14) 20 15) 24 16) 30 17) 36 18) 40 19) 45 20) 48 21) 60 22) 72 23) 80 24) 90 25) 120 26) 144 27) 180 28) 240 29) 360 30) 720

Fin de la lecture du fichier C:\DiviDe720.dta

*/

(9)

Autre exemple : fichier binaire des pays /**

* Fichier FichierBinaire2.java

* But : lire un fichier texte (Pays.Txt), créer un fichier binaire des pays.

* relire le fichier binaire et afficher : * - la liste des pays d'amérique * - la liste des pays d'océanie *

* */

import java.io.*;

public class FichierBinaire2 {

// afficher un entier (nombre) avec tant de colonnes (nbCol) static void afficher(int nombre, int nbCol) {

// construire un objet de la classe Integer Integer n = new Integer(nombre);

// convertir en chaîne String chaine = n.toString();

// afficher des espaces avant

for (int i = 1 ; i <= nbCol-chaine.length() ; i++) System.out.print(" ");

// afficher le nombre System.out.print(chaine);

}

// lire le fichier texte PAYS.TXT et créer un fichier binaire PAYS.BIN static void lireCreer(String nomTexte, String nomBinaire)

throws IOException {

// préparer le fichier à lire et à écrire

BufferedReader entree = new BufferedReader(new FileReader (nomTexte));

DataOutputStream aCreer = new DataOutputStream ( new FileOutputStream(nomBinaire));

System.out.println("\nLecture du fichier texte : " + nomTexte);

boolean finFichier = false ; while ( !finFichier ) {

// lire une ligne de texte:

String ligneLue = entree.readLine();

if (ligneLue == null) finFichier = true ; else {

char continent = ligneLue.charAt(0);

String nom = ligneLue.substring(1, 21);

String capitale = ligneLue.substring(21,41);

int superficie = Integer.parseInt(ligneLue.substring(41,51).trim());

(10)

int population = Integer.parseInt(ligneLue.substring(51).trim());

// écrire en binaire :

aCreer.writeChar(continent);

aCreer.writeChars(nom);

aCreer.writeChars(capitale);

aCreer.writeInt(superficie);

aCreer.writeInt(population);

}

}

// fermer les fichiers entree.close();

aCreer.close();

System.out.println("\nFin de la creation du fichier binaire : " + nomBinaire);

}

// afficher les pays d'un continent voulu

static void afficher(String nomBinaire, char contVoulu) throws IOException { DataInputStream aLire = new DataInputStream

( new FileInputStream(nomBinaire));

String [] nomContinents = { "Afrique", "Amerique", "Asie", "Oceanie", "Europe"};

System.out.println("\nListe des pays d'" + nomContinents[ (int) (contVoulu - 49) ]);

final int LONGUEUR = 20 ; // longueur d'un nom ou d'une capitale int rang = 0, superficie = 0, population = 0;

char continent = ' ';

String nom = "", capitale = "";

boolean finFichier = false ; while ( ! finFichier ) {

try {

continent = aLire.readChar();

} catch ( EOFException erreur ) {

finFichier = true;

}

if (!finFichier) { nom = "";

for (int i = 0 ; i < LONGUEUR ; i++) nom += aLire.readChar();

capitale = "";

for (int i = 0 ; i < LONGUEUR ; i++) capitale += aLire.readChar();

superficie = aLire.readInt();

population = aLire.readInt();

if (continent == contVoulu) { afficher(++rang, 3);

(11)

afficher(population, 11);

System.out.println();

} } }

aLire.close();

}

public static void main (String[] args)throws IOException {

lireCreer("R:\\pays.txt", "R:\\pays.bin");

afficher("R:\\pays.bin", '2'); // afficher les pays d'Amérique afficher("R:\\pays.bin", '4'); // afficher les pays d'Océanie }

}

/* Exécution:

Lecture du fichier texte : R:\pays.txt

Fin de la creation du fichier binaire : R:\pays.bin Liste des pays d'Amerique

1) CUBA LA HAVANE 114524 10500000 2) BOLIVIE LA PAZ 1100000 7100000 3) BRESIL BRASILA 8512000 147000000 4) GUATEMALA GUATEMALA CIUDAD 109000 8900000 5) ARGENTINE BUENOS AIRES 2780000 31900000 6) COLOMBIE BOGOTA 1139000 31200000 7) HONDURAS TEGUCIGALPA 112088 5000000 8) DOMINICAINE SAINT-DOMINIQUE 48400 6200000 9) EQUATEUR QUITO 270670 10500000 10) PEROU LIMA 1285000 21400000 11) COSTA RICA SAN JOSE 51000 3000000 12) SALVADOR SAN SALVADOR 21393 5200000 13) NICARAGUA MANAGUA 148000 3500000 14) PANAMA PANAMA 77000 2400000 15) JAMAIQUE KINGSTON 11425 2500000 16) URUGUAY MONTEVIDEO 177500 3000000 17) VENEZUELA CARACAS 912000 19100000 18) HAITI PORT-AU-PRINCE 27750 6400000 19) ETATS-UNIS WASHINGTON 9364000 249600000 20) CANADA OTTAWA 9975000 26300000 21) PARAGUAY ASUNCION 407000 4200000 22) MEXIQUE MEXICO 1970000 86700000 Liste des pays d'Oceanie

1) NOUVELLE ZELANDE WELLINGTON 270000 3400000 2) AUSTRALIE CANBERRA 7700000 16800000

*/

Programmer nous-même les interfaces :

(12)

Pour trier un tableau des personnes selon leurs tailles, la méthode de tri suivant fonctionne :

public static void trier(Personne [] pers, nbPers) { Personne tempo;

for(int i = 0 ; i < nbPers-1; i++) { int indMin = i;

for(int j = i+1 ; j < nbPers; j++)

if (pers[j].getTaille() < pers[indMin].getTaille() ) indMin = j;

if (indMin != i) { tempo = pers[i];

pers[i]=pers[indMin];

pers[indMin]=tempo;

} }

}

Pour trier un tableau des rectangles selon leurs surfaces, la méthode de tri suivant répond aussi à nos besoins :

public static void trier(Rectangle [] rect, nbRect) { Rectangle tempo;

for(int i = 0 ; i < nbRect-1; i++) { int indMin = i;

for(int j = i+1 ; j < nbRect; j++)

if (rect[j].getSurface() < rect[indMin].getSurface() ) indMin = j;

if (indMin != i) { tempo = rect[i];

rect[i] = rect[indMin];

rect[indMin] = tempo;

} }

}

La seule différente entre ces deux méthodes est la comparaison selon les tailles ou selon les surfaces.

Peut-on écrire une seule méthode de tri ?

(13)

interface Comparable {

public abstract boolean plusPetit(Object obj);

}

Supposons aussi que les classes Personne, Rectangle, … implémentent l’interface Camparable (en réalisant au complet la méthode plusPetit dans Personne, dans Rectangle, etc . . .).

Il suffit d’écrire une seule méthode de tri comme la suivante : // comment trier un tableau des objets COMPARABLES ? public class Tri

// tri par sélection, basée sur la méthode plusPetit de l'interface Comparable { public static void trier(Comparable[] tableau, int nbElem) {

Comparable tempo;

for(int i = 0 ; i < nbElem-1; i++) { int indMin = i;

for(int j = i+1 ; j < nbElem; j++)

if (tableau[j].plusPetit(tableau[indMin])) indMin = j;

if (indMin != i) {

tempo = tableau[i];

tableau[i]=tableau[indMin];

tableau[indMin]=tempo;

} }

} }

Pour trier les personnes : Tri.trier(pers, nbPers) ; Pour trier les rectangles : Tri.trier(rect, nbRect) ; ect …..

/** Doit-on écrire plusieurs fonctions de tri pour :

(14)

* - trier des personnes selon leur taille ? * - trier des rectangles selon leur surface ? * - trier des pays selon leur capital ?

* - trier des . . . ? *

* Réponse : NON, on peut utiliser une seule méthode * Comment ?

* Pour trier, il faut COMPARER. Cependant, l'opérateur * < (est plus petit que) n'est pas défini sur les objets * On déclare une INTERFACE dont la méthode plusPetit n'est pas * "réalisée" :

*

* interface Comparable {

* boolean plusPetit(Object c);

* } *

* Chacune de ses sous-classes (exemple Personne,

* Rectangle, ...) doit s'ENGAGER à définir (réaliser) cette

* méthode *

* Dans cet exemple, on n'a pas la notion d'héritage multiple

*/

public class TestInterface {

// afficher le tableau d'objets (personnes, rectangles, ...) static void afficher(Object [] obj, String message) {

System.out.println(message);

for(int i = 0 ; i < obj.length ; i++) System.out.println(obj[i]);

System.out.println();

}

public static void main (String[] args) {

Personne2 pers[] = { new Personne2(1.75, 65.3, 'M'), new Personne2(1.62, 69.1, 'F'), new Personne2(1.89, 76.5, 'F'), new Personne2(1.45, 50.3, 'M'), new Personne2(1.77, 90.1, 'M') };

afficher(pers, "Lite des personnes avant le tri");

Tri.trier(pers, pers.length);

afficher(pers, "Lite des personnes apres le tri");

Rectangle3 rect[] = { new Rectangle3(12, 5), new Rectangle3(9, 6), new Rectangle3(60, 12), new Rectangle3(5, 12)};

afficher(rect, "Lite des rectangles avant le tri" + " selon la surface : ");

Tri.trier(rect, rect.length);

afficher(rect, "Lite des rectangles apres le tri selon" + " la surface : ");

} }

(15)

/* Exécution :

Lite des personnes avant le tri M mesure 1.75 metre et pese 65.3 kgs F mesure 1.62 metre et pese 69.1 kgs F mesure 1.89 metre et pese 76.5 kgs M mesure 1.45 metre et pese 50.3 kgs M mesure 1.77 metre et pese 90.1 kgs Lite des personnes apres le tri M mesure 1.45 metre et pese 50.3 kgs F mesure 1.62 metre et pese 69.1 kgs M mesure 1.75 metre et pese 65.3 kgs M mesure 1.77 metre et pese 90.1 kgs F mesure 1.89 metre et pese 76.5 kgs

Lite des rectangles avant le tri selon la surface :

<longueur : 12, 5, surface : 60>

<longueur : 9, 6, surface : 54>

<longueur : 60, 12, surface : 720>

<longueur : 5, 12, surface : 60>

Lite des rectangles apres selon la surface :

<longueur : 9, 6, surface : 54>

<longueur : 12, 5, surface : 60>

<longueur : 5, 12, surface : 60>

<longueur : 60, 12, surface : 720>

*/

public class Personne2 implements Comparable { private double taille, poids;

private char sexe ;

public Personne2(double t, double p, char s) { taille = t ;

poids = p;

sexe = s;

}

public double getTaille(){

return taille;

}

public char getSexe(){

return sexe;

}

public String toString() {

return sexe + " mesure " + taille + " metre et pese " + poids + " kgs";

}

// On s'engage à implémenter la méthode "plusPetit" : public boolean plusPetit(Object p) {

return this.taille < ( (Personne2) p).getTaille();

} }

(16)

public class Rectangle3 implements Comparable

{ // attributs (champs de données, membres de données) private int longueur, largeur;

public Rectangle3() { }

public Rectangle3(int lo, int largeur) { longueur = lo;

this.largeur = largeur;

}

public Rectangle3(int c) { this(c, c);

}

// méthode pour calculer et retourner le périmètre public int perimetre(){

return 2 * (longueur + largeur);

}

// méthode pour calculer et retourner la surface public int surface() {

return longueur * largeur ; }

public int getLongueur() { return longueur ; } public int getLargeur() { return largeur ; }

// On s'engage à IMPLÉMENTER la méthode "plusPetit" public public boolean plusPetit(Object r) {

return this.surface() < ( (Rectangle3) r).surface();

}

public String toString() {

return "<longueur : " + longueur + ", " + largeur + ", surface : "

+ surface() + ">";

} }

interface Comparable {

public abstract boolean plusPetit(Object obj);

}

Classes concrètes vs abstraites vs interfaces :

(17)

Création une instance avec new Oui Non Non Supporte des méthodes

abstraites Non Oui Oui

Supporte de l’héritage multiple Non Non Oui

Droits des constructeurs Oui Oui Oui

Implémentation d’une méthode nécessaire Oui si non

abstraite Non car toutes sont abstraites

Contenu Illimité Illimité public static

final et

Méthodes abstraites

Constatation : Dans Swing, il existe plusieurs interfaces (IFT 1176) :

Interface Summary

Action

The JFC Action interface provides a useful extension to the ActionListner interface in cases where the same functionality may be accessed by several controls.

BoundedRangeModel Defines the data model used by components like Sliders and ProgressBars.

ButtonModel State Model for buttons.

CellEditor This interface defines the methods any general editor should be able to implement.

ComboBoxEditor The editor component used for JComboBox components.

ComboBoxModel

ComboBoxDataModel is a ListDataModel with a selected item This selected item is in the model since it is not always in the item list.

DesktopManager DesktopManager objects are owned by a JDesktopPane object.

Icon A small fixed size picture, typically used to decorate

components.

JComboBox.KeySelectionManager The interface that defines a KeySelectionManager.

etc . . .

Références

Documents relatifs

- très peu de réflexion : nombreux sont les candidats capables d'annoncer que le poids n'intervient pas tout en calculant son influence à la question suivante (E1.1/E1.2).. - peu

NO SENSE and ILI are set in the sense data (see below for VALID). The tape is left on the EOT side of the &#34;faulty&#34; block, which is not transferred to the INITIATOR. The use

*Hors presse, livres, gaz et carburants.**Voir modalités, produits éligibles à l’offre et liste des magasins participants sur www.tupperware.intermarche.com et dans le

Place des méthodes de purification dans l'étude des interactions acides

Maintenant, nous partageons rintégrale(22)en deux parties dans lesquelles t varie respectivement entre o et un nombre a^&gt;s, et entre a et oo.. NON-TOTALITÉ DE CERTAINES

Les représentants des Fédérations syndicales, invités à s’exprimer en début de séance se sont fait l’écho des sérieuses difficultés rencontrées dans le réseau, la

Afin de résoudre certaines équations en régime sinusoïdal, on utilise assez souvent la représentation complexe.. On va rappeler grâce à cet exercice les limites d’utilisation

Une classe dérivée d’une classe non abstraite peut être déclarée abstraite et/ou contenir des méthodes abstraites... Java Classes et