• Aucun résultat trouvé

Classe abstraite (abstract class):

N/A
N/A
Protected

Academic year: 2022

Partager "Classe abstraite (abstract class):"

Copied!
1
0
0

Texte intégral

(1)

Classe abstraite (abstract class):

Pourquoi ?

Lors de la conception d'une hiérarchie, on a besoin de créer des classes plus générales d'abord et différer l'implémentation à des étapes plus éloignées quand le comportement est très bien défini. Quand on parle de figure géométrique, il est trop vague pour savoir comment calculer un périmètre, une surface : ces méthodes sont encore abstraites. Il est impossible de réaliser (implémenter) ces méthodes. Par contre, un rectangle est une figure géométrique dont le calcul du périmètre et de la surface est connu, on peut alors implémenter ces méthodes qui sont très concrètes (pas du tout abstraites) pour un rectangle.

classe abstraite : Figure géométrique

peut-on calculer :

1) le périmètre de n'importe quelle figure ? non! => ce calcul est abstrait!

2) la surface de n'importe quelle figure ? non! => ce calcul est abstrait!

classe

Parallelogramme

périmètre : Oui

2x(cote1+cote2)

surface : Non encore abstraite

classe Cercle périmètre : Oui

2xMath.Pi x rayon

surface : Oui Math.Pi x rayon

2

classe Triangle périmètre : Oui

côté1+côté2+côté3

surface : Non

classe Rectangle

surface : Oui

longueur x largeur classe concrète

classe

TriangleRectangle

surface : Oui

hauteur x base / 2 classe concrète

En résumé : une classe abstraite est celle qui n'est que partiellement implantée

et dont l'intérêt est la conception d'une hiérarchie de l'héritage simple.

(2)

/** classe abstraite FigureGeometrique

* 1. cette classe contient au moins une méthode abstraite * la classe est donc abstraite

* 2. On n'a pas de formule pour caculer le périmètre * ni de surface de n'importe quelle figure.

* À cette étape-ci, les deux méthodes sont encore abstraites * 3. On n'a pas le droit d'avoir des objets construits (avec new) * d'une classe abstraite

* 4. On a le droit d'avoir des méthodes non abstraites (concrètes) * (la réalisation de la méthode est faite au complet,

* exemple toString() de FigureGeometrique) */

public abstract class FigureGeometrique {

public abstract double perimetre();

public abstract double surface();

public String toString() {

return "Perimetre : " + perimetre() + "\n" + "Surface : " + surface() + "\n";

} }

/**

* Pour un parralelogramme (côtés opposés parallèles) :

* - le calcul du périmètre est concret : 2 x (côté1 + côté2) * - le calcul de la surface est encore abstraite

* la classe Parallelogramme est encore abstraite *

* On n'a pas le droit d'avoir d'objets construits avec new * pour la classe abstraite Parallelogramme

* Cependant, on a le droit d'avoir des constructeurs!

* (pour appeler avec this(...) ou super(....) */

public

abstract

class Parallelogramme extends FigureGeometrique

{ private double cote1, cote2 ;

public Parallelogramme(double cote1, double cote2) { this.cote1 = cote1;

this.cote2 = cote2;

}

public double perimetre() { return 2 * (cote1+cote2); }

// public abstract double surface();

public double getCote1() { return cote1; } public double getCote2() { return cote2; } }

(3)

/**

* On a choisi le nom Rectangle2 afin d'éviter des anciens * exemples sur Web avec Rectangle.java

*

* Les 2 méthodes :

* perimetre() : hériter de Parallelogramme

* surface() : implémentée ici (réaliser de A à Z) * La classe Rectangle2 n'est plus abstraite. Elle est * concrète.

*/

public class Rectangle2

extends Parallelogramme {

// appel le constructeur d'une super-classe (qui est abstraite!) public Rectangle2(double lo, double la) {

super(lo, la);

// ainsi côté1 <-> longueur,côté2 <-> largeur }

public double surface() {

return getCote1() * getCote2();

}

public String toString() {

return "Rectangle : <longueur = " + getCote1() + ", largeur = " + getCote2() + ">\n" + super.toString();

// appel d'une méthode de la super-classe /* notez que Java ne trouve pas toString() dans

Parallelogramme. Il va monter jusqu'à FigureGeometrique et applique le toString() de FigureGeometrique

C'est le polymorphisme : appliquer la bonne méthode */

} }

// Révision de l'héritage, du polymorphisme

public class Carre2 extends Rectangle2

{

public Carre2(double cote) { super(cote,cote);

}

public double diagonale() {

return getCote1() * Math.sqrt(2.0);

}

public String toString() {

return super.toString() + "Diagonale : " + diagonale() + "\n";

} }

(4)

/**

* On a choisi le nom Circle afin d'éviter des anciens * exemples sur Web avec Cercle.java

*

* Les 2 méthodes :

* perimetre() : implémentée ici (réaliser de A à Z) * surface() : implémentée ici (réaliser de A à Z) * La classe Circle n'est pas abstraite. Elle est * concrète.

*/

public class Circle

extends FigureGeometrique

{

private double rayon;

public Circle( double rayon ) { this.rayon = rayon;

}

public double perimetre() { return 2 * Math.PI * rayon; } public double surface() { return Math.PI * rayon * rayon;}

public String toString() {

return "Cercle de rayon " + rayon + "\n" + super.toString();

}}

/** classe TestAbstraite

* Pour cet exemple, on se limite au minimum pour faire * ressortir le concept de classe abstraite.

*

* Exercice :

* ajouter une classe Triangle. Pourquoi est-elle abstraite ? * ajouter une sous-classe TriangleRectangle.

* Pourquoi est-elle concrète ? * Tester le bon fonctionnement *

* *

* Les classes abstraites se trouvent à plusieurs places * dans les paquets de Java (comme java.io, java.lang, ...).

* La gestion des fichiers (textes, binaires, ...) utilise * certaines classes abstraites.

*/

public class TestAbstraite

{ static double surfaceTotale(FigureGeometrique[] tableau) { double totSurface = 0.0;

for (int i = 0 ; i < tableau.length ; i++) totSurface += tableau[i].surface();

return totSurface;

}

(5)

public static void main (String[] args) {

/*

Message d'erreur du genre suivant:

L'operateur new est interdit pour une instance de la classe abstraite FigureGeometrique

FigureGeometrique fg = new FigureGeometrique();

*/

Rectangle2 rect1 = new Rectangle2(10.0,6.5);

System.out.println("Infos de rect1 :\n" + rect1);

Circle c1 = new Circle(10.0);

System.out.println("Infos du cercle c1 :\n" + c1);

FigureGeometrique[] tabFG = { new Rectangle2(10.0, 4.0),

new Circle(5.0),

new Rectangle2(8.6, 4.4), new Rectangle2(14.2, 10.8), new Carre2(6.0)};

System.out.println("Surface totale pour acheter " + "de la peinture: " +

surfaceTotale(tabFG));

} }

/* Exécution:

Infos de rect1 :

Rectangle : <longueur = 10.0, largeur = 6.5>

Perimetre : 33.0 Surface : 65.0 Infos du cercle c1 : Cercle de rayon 10.0

Perimetre : 62.83185307179586 Surface : 314.1592653589793

Surface totale pour acheter de la peinture: 345.73981633974483

*/

Constatations avec quelques classes de Java

classe Object

(6)

public abstract class java.lang.Number extends java.lang.Object {

public abstract int intValue();

public abstract double doubleValue();

public abstract long longValue();

public abstract float floatValue();

}

public final class java.lang.Integer extends java.lang.Number

{ …….

public int intValue();

public double doubleValue();

public long longValue();

public float floatValue();

…….

}

public final class java.lang.Double extends java.lang.Number

{ …….

public int intValue();

public double doubleValue();

public long longValue();

public float floatValue();

…….

}

etc

Les méthodes de conversion d’un nombre en entier, réel sont abstraites quand on ne connaît pas encore la nature du nombre (dans Number). Par contre, dans chacune des 4 sous-classes de Number : Integer, Double, Long, Float les nombres sont très bien définis en syntaxe => la conversion est faisable. Les méthodes de conversion sont alors bien implémentées dans ces 4 classes.

Lecture d’un fichier texte :

classe Object

public abstract class java.io. Reader

abstract void close() ; // Close the stream.

abstract int read(char[] cbuf, int off, int len)

// Read characters into a portion of an array.

(7)

public class java.io.

InputStreamReader extends Reader

public class java.io. BufferedReader

extends Reader

un constructeur:

public BufferedReader(Reader in)

Create a buffering character-input stream that uses a default- sized input buffer.

Parameters: in - A Reader public void close()

throws IOException Close the stream.

Overrides: close in class Reader

Throws: IOException - If an I/O error occurs public String readLine()

throws IOException Read a line of text.

public class java.io. FileReader extends InputStreamReader

un des constructeurs :

public FileReader(String fileName) throws IOException

… autres constructeurs + methodes …..

On constate qu’une classe abstraite (exemple BufferedReader) contient au moins une méthode abstraite (exemple : abstract void close()).

Création d’un fichier texte :

classe Object

public abstract class java.io.Writer extends Object

abstract

void close()

; // Close the stream, flushing it first.

abstract

void flush()

; // Flush the stream.

(8)

void write(char[] cbuf)

; // Write an array of characters.

etc …. etc ….

public class java.io.

OutputStreamWriter

extends Writer

public class java.io. PrintWriter

extends Writer

un constructeur:

public PrintWriter(Writer out);

public void println(String x);

Print a String and then terminate the line.

public class java.io. FileWriter extends OutputStreamWriter

un des constructeurs :

public FileWriter(String fileName) throws IOException

… autres constructeurs + methodes …..

Exemple de lecture et de création de fichier(s) texte(s) :

L’utilisation d’une pile est pour seul but de réviser techniquement les notions de l’héritage, du polymorphisme.

public class Employe {

private char poste ; private int numero;

private double nbHr, taux;

public Employe(char poste, int numero, double nbHr, double taux) { this.poste = poste;

this.numero = numero;

this.nbHr = nbHr;

this.taux = taux;

}

public String nomPoste() { String ch = "";

switch (poste) {

case 'A' : ch = "Analyste"; break;

case 'P' : ch = "Programmeur"; break;

case 'O' : ch = "Operateur"; break;

(9)

case 'S' : ch = "Secretaire";

}

return ch;

}

public char getPoste() { return poste;

}

public double getHr() { return nbHr;

}

public String toString() {

return numero + "\t" + nbHr + "\t" + taux + "\t" + nomPoste() + "\n";

}

}

import java.io.*;

import java.util.*;

public class Texte {

static Stack lireRemplir (String nomFichier) throws IOException {

Stack pile = new Stack();

boolean existeFichier = true ; // à ajuster après FileReader fr = null; // initialiser pour Java

// essayer try {

fr = new FileReader (nomFichier) ; }

catch ( java.io.FileNotFoundException erreur) // intercepter l'erreur {

System.out.println("Probleme d'ouvrir le fichier " + nomFichier);

existeFichier = false ; // ajuster }

if (existeFichier) {

// un modèle de lecture d'un fichier:

BufferedReader entree = new BufferedReader(fr);

boolean finFichier = false ; while ( !finFichier ) {

String ligneLue = entree.readLine();

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

char poste = ligneLue.charAt(0);

(10)

int numero = Integer.parseInt(ligneLue.substring(3,7));

double nbHr = ( new Double(ligneLue.substring(8,13))).doubleValue();

double taux = ( new Double(ligneLue.substring(18,23))).doubleValue();

Employe emp = new Employe(poste, numero, nbHr, taux);

pile.push(emp);

}

}

entree.close();

System.out.println("On vient de creer une pile contenant " + pile.size() + " employes ");

}

return pile;

}

static void creerFile(Stack pileEmp, char posteVoulu, double borne, String nomACreer) throws IOException {

PrintWriter aCreer = new PrintWriter( new FileWriter(nomACreer));

for (int i = 0; i < pileEmp.size(); i++)

if ( ((Employe) pileEmp.elementAt(i)).getPoste() == posteVoulu && ((Employe) pileEmp.elementAt(i)).getHr() > borne )

aCreer.print(pileEmp.elementAt(i));

aCreer.close();

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

}

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

Stack pileEmp = lireRemplir("R:\\employes.txt");

creerFile(pileEmp, 'P', 42.0,"R:\\Program.P42");

creerFile(pileEmp, 'A', 35.0,"R:\\Analyste.P35");

} }

/* Exécution:

On vient de creer une pile contenant 243 employes Fin de la creation du fichier R:\Program.P42 Fin de la creation du fichier R:\Analyste.P35 Contenu du fichier R:\Program.P42

1350 42.01 29.02 Programmeur 1550 42.04 29.04 Programmeur 1627 42.06 36.06 Programmeur 3751 42.12 30.09 Programmeur 3747 42.13 36.1 Programmeur 5056 42.18 35.13 Programmeur 5012 42.19 31.14 Programmeur 4122 42.23 31.16 Programmeur 2811 42.27 30.19 Programmeur 3321 42.28 30.2 Programmeur 4959 42.31 38.21 Programmeur 3216 42.36 35.24 Programmeur

(11)

5059 42.38 38.26 Programmeur 3133 42.45 32.3 Programmeur 4421 42.52 30.34 Programmeur 1601 42.53 30.35 Programmeur 4915 42.56 34.37 Programmeur Contenu du fichier R:\Analyste.P35 3834 35.05 42.99 Analyste

4509 35.06 43.07 Analyste 1429 35.09 43.19 Analyste 4909 35.65 45.99 Analyste 2629 35.67 46.11 Analyste 2074 35.8 46.75 Analyste

*/

Règles à respecter d'une classe abstraite : . pas d'instanciation (trop abstraite pour la construction d'un objet avec new)

. une classe abstraite a le droit des constructeurs (qui seront appelés par autres constructeurs avec this(…) ou super(…))

. une classe abstraite doit contenir au moins une

déclaration de méthode abstraite (cas très fréquent) ou de variable abstraite

. une méthode abstraite déclarée dans la classe abstraite doit être implémentée dans une de ses sous-classes (pas nécessairement dans toutes ses sous-classes)

. la classe dans laquelle une méthode abstraite est déclarée ne comporte pas de code pour cette méthode.

Il n'est pas nécessaire d'implémenter une méthode abstraite dans chaque sous-classe (clause avant).

. une classe abstraite ne peut pas être déclarée comme final (pas de sous-classes) ou private (car on ne peut pas utiliser ses méthodes à l'extérieur de cette classe abstraite).

Notez que les classes Math, String sont déclarées comme "final".

Déclaration :

visibilité abstract class nomDeClasse { ….

visibilité abstract type nomDeMethode(liste d'arguments) ; ….

}

Références

Documents relatifs

with 4F2hc] Na + indep.: cationic amino acids; Na + depen.: large neutral l -amino acids (system y + L) E (preferentially intracellular cationic amino acid for extracellular

Les enjeux didactiques de la notion de praxéologie structuraliste sont discutés en relation avec les difficultés identifiées dans l'enseignement

Le but de ces questions est de demander aux étudiants de récapituler les œuvres visitées, ce qui constitue une étape dans leur appropriation, sachant bien

le constructeur de chaque classe se compose des diff´erents sous-arbres de l’alternative correspondante dans la grammaire ; l’option est exprim´ee par la classe Option de Scala :.

Similairement, la catégorisation dans T ROPES signale que la classe catégorisée peut être spécialisation de n’importe laquelle de ses classes les plus générales et

Therefore, in our study (mechanical properties and internal fit of four CAD CAM block materials), different CAD CAM block materials were tested from different groups of

Les instituts à apostolat mixte (enseignement, soins et œuvres diverses) occupent le troi- sième rang, avec 77 religieuses. Les hospitalières et les congrégations à but

Créer la classe abstraite Titulaire (public abstract class Titulaire extends Prof) qui possède la méthode abstraite setCouleurDefaut (public abstract void