COURS POO C#

130
Programmation Orientée Objet (POO) 21/03/2013 1 A.ELmagri

Transcript of COURS POO C#

Programmation Orientée Objet (POO)

21/03/2013 1 A.ELmagri

PLAN

Introduction à la POO (Classes et Objets) Programmation Objet C# Les Classes en C# Encapsulation et Méthodes d‟accés Héritage Classes de collections Polymorphisme Les exceptions

21/03/2013 2 A.ELmagri

Définition

Programmation orientée objet (ou POO):

Technique visant à faire interagir des objets entre eux,

Facilite l‟écriture des applications par une structuration en terme d‟objets.

Favorise la réutilisation de code, en composant des programmes à partir d‟objets existants (par exemple, la bibliothèque standard de C++, de Java, . . .).

21/03/2013 3 A.ELmagri

Concepts clefs de la POO Deux notions essentielles sont caractéristiques de la POO :

Classe : schématiquement, une classe représente le type d’un objet, tout comme int représente un entier.

Objet : constitué par l‟association d‟une quantité

d‟information organisée en champs (nom, prénom, age, notes pour un étudiant ; marque, modèle, cylindrée, vitesse pour une voiture) et d‟un ensemble de méthodes permettant d‟interagir avec lui (calculer la moyenne d‟un étudiant ou accélérer pour une voiture).

21/03/2013 4 A.ELmagri

Objet Objet = identité + état + comportement

Une identité

deux objets différents ont des identités différentes

on peut désigner l‟objet (y faire référence)

Un état (attributs)

Ensemble de propriétés/caractéristiques définies par des valeurs

Permet de le personnaliser/distinguer des autres objets

Peut évoluer dans le temps

Un comportement (méthodes)

Ensemble des traitements que peut accomplir un objet (ou que l‟on peut lui

faire accomplir)

21/03/2013 5 A.ELmagri

Objet - Exemples

Objet Etat Comportement

Chien Nom, race, âge, couleur.. Aboyer, chercher le bâton,

mordre..

Compte N°, type, solde.. Retrait, virement, dépôt,

consultation de solde

Téléphone N°, marque, sonnerie,

répertoire, opérateur

Appeler, Prendre un appel,

Envoyer sms, charger

21/03/2013 6 A.ELmagri

Classes et instances (1) Classe = patron/moule (= type)

une classe est la « description » d‟une collection objets homogènes (mêmes caractéristiques et mêmes comportements).

décrit la structure de l‟état (les attributs et leurs types)

Instance = objet obéissant à un patron un objet est une « instance » de classe. Par analogie, on peut aussi considérer une classe comme le type d‟une

variable et l‟objet comme la valeur de cette même variable.

Classe : abstrait la notion/le type “Chat”

Instance : concret “ce Chat blanc que je vois dans la rue”, “le chat de mon voisin”

21/03/2013 7 A.ELmagri

Classes et instances (2) Une classe doit nécessairement comporter les éléments suivants :

Les champs : ce sont les « variables » permettant, en général, de définir l’état de l‟objet.

Un ou plusieurs constructeurs : ce sont des fonctions indiquant de quelle façon l‟objet doit être déclaré et initialisé.

Les méthodes : ce sont les fonctions permettant d’agir sur les objets d‟une classe. Selon leur définition, elle peuvent s‟appliquer sur un objet particulier, ou sur l‟ensemble des instances d‟une classe.

21/03/2013 8 A.ELmagri

Exemples La classe « chien » définit:

Les attributs d‟un chien (nom, race, couleur, âge…)

Les comportements d‟un chien (Aboyer, chercher le bâton, mordre…)

Il peut exister dans le monde plusieurs objets (ou instances) de chien!!

21/03/2013 9 A.ELmagri

Classe Instances (Objets)

Chien - Mon chien: Bill, Teckel, Brun, 1 an

- Le chien de mon voisin: Hector, Labrador, Noir, 3 ans

Compte -Mon compte à vue: N° 210-1234567-89, Courant, 1.734 DZ,12.500DZ

-Mon compte épargne: N° 083-9876543-21, Epargne, 27.000 DZ, 0DZ

21/03/2013 A.ELmagri 10

Programmation Objet C#

21/03/2013 A.ELmagri 11

Un espace de nom est un ensemble de classes associées, il peut également contenir d‟autres espaces de nom.

Exemple :

namespace MesClasses

{

public class ClasseUne

{ ... }

public class ClasseDeux

{ ... }

}

Espace de nom (namespace)

Imbrication des espaces de noms

21/03/2013 A.ELmagri 12

L'imbrication des espaces de noms est possible :

namespace MesClasses {

namespace Calcul {

// espace de nom MesClasses.Calcul

}

}

Ou directement :

namespace MesClasses.Calcul {

... // espace de nom MesClasses.Calcul

}

Espace de noms en plusieurs parties

21/03/2013 A.ELmagri 13

Plusieurs fichiers sources peuvent contribuer à ajouter des déclarations à un même espace de noms.

Fichier : images.cs

using System;

namespace Exemple.Images {

public class Image { ... }

public class ImageBitmap : Image { ... }

... }

Fichier : couleurs.cs

using System;

namespace Exemple.Images {

public class Couleur { ... }

public class ConversionCouleur { ... }

... }

Directive using

21/03/2013 A.ELmagri 14

Le mot clé using fait référence aux ressources dans la librairie des

classes de .NET Framework

C# est fourni avec de nombreuses classes d‟utilitaires qui

effectuent diverses opérations utiles

Ces classes sont organisées en espace de nom (namespace)

Une directive using spécifie un espace de nom qui sera utilisé

Les variables et les constantes

21/03/2013 A.ELmagri 15

Une variable réserve une place en mémoire pour stocker

des données.

Déclaration:

type nom [ = expression ] ;

Une constante nommée est associée à une valeur pour

toute la durée de l'application. Sa valeur ne peut changer.

Déclaration:

const type nom = expression ;

Votre premier Programme en C#

21/03/2013 A.ELmagri 16

Les Entrées / Sorties (In/Out)

21/03/2013 A.ELmagri 17

La classe Console

- La classe Console fournit un accès à l‟entrée standard, à la sortie standard et aux flux d‟erreur standard

- Les méthodes Console.Write et Console.WriteLine affichent des informations sur l‟écran de la console.

-Les méthode Console.Read et Console.ReadLine lisent l‟entrée de l‟utilisateur sur le clavier.

Appeler ReadKey à la fin de la méthode Main empêche que la fenêtre de console ne se ferme avant que vous ayez pu lire la sortie lorsque vous lancez le mode débogage en appuyant sur F5.

La méthode Main

21/03/2013 A.ELmagri 18

L‟exécution d‟une application C# démarre au niveau de la

méthode Main.

Une application C# peut contenir plusieurs classes, mais un

seul point d‟entrée.

On peut avoir plusieurs classes avec Main dans la même

application, mais une seule méthode Main est exécutée.

La classes à utiliser doit être spécifiée lors de la compilation

de l‟application.

La méthode Main

21/03/2013 A.ELmagri 19

Déclarez la méthode Main d'une des manières suivantes :

Elle peut retourner void :

Elle peut également retourner int :

Avec les deux types de retour, elle peut accepter des arguments :

Le paramètre de la méthode Main est un tableau string qui représente les arguments de la ligne de commande utilisés pour appeler le programme.

Classe

21/03/2013 A.ELmagri 20

Classe :

Dans C#, une application est une collection d‟une ou plusieurs classes, structure de données et autres types.

Les classes peuvent être réparties dans un ou plusieurs fichiers

Plusieurs classes peuvent être placées dans un fichier

Membres d'une classe:

Les fonctions, appelées méthodes, traitent les données, appellent d'autres méthodes, retournent éventuellement une valeur ;

Les variables, appelées attributs, stockent les données ;

Exemple de Classe:

21/03/2013 A.ELmagri 21

Public class Rectangle {

//Les attributs (ou proprietes ou Etat) de la classe

Int largeur ;

Int longueur ;

//Implémentation des methodes (comportement)

Int Calcule_surface( ) {

Return (largeur*longueur) ;

}

}

Instanciation d’un objet

21/03/2013 A.ELmagri 22

Pour qu‟un objet ait une existence, il faut qu‟il soit instancié.

Une même classe peut être instanciée plusieurs fois, chaque instance (objet) ayant des propriétés ayant des valeurs spécifiques.

Par exemple l‟instanciation d‟un objet de type Client se fait comme suit :

Public static void Main(String[] args) {

Rectangle rect ; //déclaration d’une variable de type Classe

rect = new Rectangle( ) ; //instanciation d’un objet rectangle

}

I. Encapsulation - Méthodes

d’accès - Constructeurs

21/03/2013 23 A.ELmagri

Encapsulation

21/03/2013 A.ELmagri 24

Mécanisme permettant de rassembler les attributs et méthodes propres à un type donné afin d‟en restreindre l‟accès et/ou d‟en faciliter l‟utilisation et la maintenance

De manière générale, les données sont privées et les méthodes sont publiques

Certaines méthodes peuvent être privées et ne servir qu‟au fonctionnement interne de la classe

public : Accès autorisé tous ;

private : Accès depuis la classe seulement ;

Protected : Accès depuis la classe et ses sous-classes seulement ;

Si l‟accès à un attribut de classe n‟est pas défini, le compilateur C# le considèrera par défaut comme privé

Les méthodes d’accès aux propriétés

21/03/2013 A.ELmagri 25

Si les propriétés sont verrouillées (déclarées private) on ne

peut plus y accéder de l’extérieur de la classe. Il

faut donc créer des méthodes pour avoir accès aux

propriétés, ces méthodes doivent permettre un

accès dans les deux sens :

Les Accesseurs/Setters : Pour modifier la valeur de

propriété.

Les mutateurs/Getters: Pour connaitre la valeur de la

propriété.

Les accesseurs (getters) :

21/03/2013 A.ELmagri 26

Ces méthodes sont appelées des méthodes de type Get, cette méthode (fonction) ne prend pas de paramètre et retourne la valeur de l‟attribut associé.

Par exemple pour l‟attribut largeur de type int , la fonction Get serait déclaré comme suit :

Public int GetLargeur() {

return largeur;

}

Cette fonction pourra être utilisée dans la fonction Main comme suit : Rectangle rect = new Rectangle () ;

Int large= rect.GetLargeur() ;

Les mutateurs/Setters

21/03/2013 A.ELmagri 27

Ces méthodes sont appelées méthodes Set. Cette méthode n’a

aucun retour (procédure). Par contre un paramètre de même

type que la propriété doit lui être indiqué.

Le Setter associé à la propriété Largeur de la classe Rectangle

sera implémenté comme suit

public void SetLargeur (int large){

largeur = large; }

Cette fonction pourra être utilisée dans la fonction Main , comme

suit : Rectangle rect = new rectangle( ) ;

rect.SetLargeur(20);

Exemple:

21/03/2013 A.ELmagri 28

Public Class Rectangle {

/* L’etat de la classe – les attributs*/

private int largeur;

Private int longueur;

/* les getters et setters des attributs */

public void SetLongueur (int long) {

this.longueur = long;}

public int GetLongueur () {

return this.longueur; }

public void SetLargeur (int large) {

this.largeur = large; }

public int GetLargeur () {

return this.largeur; }

/* Eventuellement autres méthodes*/

……….;

}

Les Constructeurs(1)

21/03/2013 A.ELmagri 29

Un constructeur d‟une classe intervient au moment de l‟instanciation d‟un objet de type cette même classe.

Le constructeur initialise les attributs (propriétés) de cet objet pour qu‟il soit cohérent.

Le constructeur est une méthode de la classe, mais très particulière :

Parce qu‟elle a le même nom que l’identificateur de la classe.

Parce qu‟elle n’a pas de type de retour, même le type void.

Les Constructeurs(2)

21/03/2013 A.ELmagri 30

Pour une classe donnée, on peut définir plusieurs

constructeurs.

Tous ces constructeurs partagent le même nom (le nom de

la classe), mais se distinguent par le nombre et les types

d‟arguments, cette distinction s‟appelle en orientée objet

surcharge.

Constructeur d’initialisation :ce constructeur initialise

les propriétés de l‟objet au moment de l‟instanciation, par les

valeurs passées en paramètre.

Constructeur / Exemple

21/03/2013 A.ELmagri 31

Public class Client {

//Déclaration des attributs

Private int num ;

Private string nom ;

Private double chiffre_affaire ;

//Implémentation d’un constructeur d’initialisation

Public Client(int numero, string name, double ca){ This.num=numero ;

This.nom=name;

This.chiffre_affaire=ca; } }

Cela va permettre d‟instancier la classe Client dans Main de la façon suivante :

Client cli = new Client(100, “toto”, 10000);

Constructeur par défaut

21/03/2013 A.ELmagri 32

Un constructeur par défaut existe déjà pour chaque classe si aucun autre constructeur n‟est déclaré.

A partir du moment où le constructeur d‟initialisation existe, il devient impossible d‟appeler le constructeur par défaut.

/* faux , impossible d’appeler le constructeur par déaut*/

Client cli = new Client () ;

Pour remédier à ce problème, il suffit de rajouter le constructeur par défaut dans la classe Client:

/* constructeur par défaut */

Public Client ( ) { }

Constructeur de recopie

21/03/2013 A.ELmagri 33

Le constructeur de recopie permet de copier les propriétés d‟un objet existant dans une nouvelle instance(objet).

Exemple de constructeur de recopie :

public Client (Client c) {

This.num = c.num ; This.nom = c.nom;

This.chiffre_affaire = c.chiffre_affaire; }

Dans le programme principal:

cl1t=new Client(234, « toto » , 9876) ;

Client clt2=new Client(clt1) ; //Constructeur de recopie

Propriété de classe

21/03/2013 A.ELmagri 34

En C#, chaque classe peut avoir un compteur d‟instance qui

a comme valeur le nombre d‟instances en cours, instanciées à

partir de cette classe à un moment donnée.

Ce compteur d‟instance est une propriété de classe, sa

valeur est la même pour toutes les instances, pour déclarer

cette propriété on utilise le mot static.

La propriété de la classe doit être initialisée par 0 lors de sa

déclaration, et incrémentée de 1 dans tous les constructeurs

de la classe.

Propriété de classe: Exemple

21/03/2013 A.ELmagri 35

Public class Client {

//propriété de classe

private static int compteur=0 ;

//propriété d‟instance

private int num ; Private string nom ;

private double ca ;

//constructeur par défaut

public Client() { compteur+=1 ; }

//Constructeur d’initialisation

public Client(int num, string nom, double ca) {

compteur+=1 ; This.num=num ; This.nom=nom ; This.ca=ca ; }

//Constructeur de recopie

Public Client(Client clt) { compteur+=1 ; This.num=clt.num ; This.nom=clt.nom ; This.ca=clt.ca; } }

Les méthodes de classe

21/03/2013 A.ELmagri 36

Une méthode de classe est une méthode private déclarée avec le mot clé static .

Exemple :

Méthode Get associée à la propriété de classe « compteur:

private static int GetCompteur(){

Return compteur ; }

L‟appel d‟une méthode de classe est sensiblement différent à l‟appel des autres méthodes.

Public static void Main(string[]args){

// utilisation de la classe elle-même, et pas une instance

int cpt= Client.GetCompteur();

}

Exemple: Classe Personne

21/03/2013 A.ELmagri 37

public class personne{

// Attributs de la classe

private static long nbPersonnes=0;

// Attributs d’objet

private String _prenom;

private String _nom;

private int _age;

// Constructeurs

public personne(String p, String n, int age)

{

// Incrementer le nbre d’instance

nbPersonnes++;

this._prenom=p;

this._nom=n;

this._age=age; }

}

public personne(personne P){ // Incrementer le nbre d’instance

nbPersonnes++;

this._prenom=p._prenom;

this._nom=p._nom;

this._age=p._age;

}

// Méthode de la classe

public static long GetNbPersonnes{

return _nbPersonnes;

}

/* setters et getters */

…………………. }

Dans la méthode Main:

public static void Main(){

personne p1=new personne("Jean","Dupont",30);

personne p2=new personne(p1);

new personne(p1);

Console.Out.WriteLine("Nombre de personnes

créées : "+personne.nbPersonnes);

}

Classe statique

21/03/2013 A.ELmagri 38

Une classe statique ne contient que des membres statiques, et ne peut être instanciée. Le mot clé static précède la déclaration de cette classe.

Exemple :

public static class UneClasseStatique{

public static void Afficher(string message) {

// ...

}

}

Utilisation :

UneClasseStatique.Afficher("Un exemple de message");

II. L’Héritage

21/03/2013 39 A.ELmagri

C’est quoi l’Héritage ?(1)

21/03/2013 A.ELmagri 40

Imaginons que nous avons les classes suivantes: Etudiant, Enseignant,

Salarie.

Nous remarquons que les champs nom, prenom, age ainsi que

leurs getters et setters sont répètes dans les 3 classes !!

Etudiant

String nom

String prenom

Int age

Int cne

getNom()

getPrenom()

getAge()

getCne()

Enseignant

String nom

String prenom

Int age

Int matricule

String etablissement

getNom()

getPrenom()

getAge()

getMatricule ……

Salarie

String nom

String prenom

Int age

Int matricule

getNom()

getPrenom()

getAge()

getMatricule

C’est quoi l’Héritage ?(2)

21/03/2013 A.ELmagri 41

De même, la classe Enseignant et la classe Salarie partagent

4 champs ( matricule de plus!).

Afin d'éviter la répétition des éléments constituant

chacune des classes, il est préférable de factoriser toutes

ces caractéristiques communes pour en faire une

nouvelle classe plus généraliste.

On peut penser à une classe Personne:

Personne

String nom

String prenom

Int age

GetNom()

GetPrenom()

GetAge()

…..

Cette classe contiendra les champs et

les méthodes communs de classes

Enseignant, Salarie, et Etudiant.

C’est quoi l’Héritage ?(3)

21/03/2013 A.ELmagri 42

Ainsi Etudiant, Salarie et Enseignant ne sont que des exemples

particuliers de Personne! Et qui Héritent tous les

caractéristiques de la Personne.

Personne

String nom

String prenom

Int age

GetNom()

GetPrenom()

GetAge()

…..

Etudiant

Int cne

getCne()

Enseignant

Int matricule

String etablissement

getMatricule ()

getEtablissement()…

Salarie

Int matricule

getMatricule()

Nous remarquons que les

attributs encapsulés dans

la classe Personne, ne

figurent plus dans les

trois classes Dérivées

/FILLES

Classe Parente

(Mère)

On dit que la classe Salarie

Hérite de la classe Personne

( elle hérites tous les

attributs et les méthodes)

21/03/2013 A.ELmagri 43

Nous remarquons aussi, que Enseignant est en fait un Salarie, et que la

caractéristique Matricule est en commun, donc on peut penser à faire

une liaison d’héritage entre Salarie et Enseignant comme suit:

Personne

String nom

String prenom

Int age

GetNom()

GetPrenom()

GetAge()

…..

Etudiant

Int cne

getCne() Enseignant

String etablissement

getEtablissement()……

Salarie

Int matricule

getMatricule()

Pour récapituler !

21/03/2013 A.ELmagri 44

L’héritage consiste en la création d‟une nouvelle classe dite classe drivée ou classe fille à partir d‟une classe existante dite classe de base ou classe parente ou encore classe mère.

L’héritage permet de :

Récupérer le comportement standard d‟une classe objet (classe mère) à partir de propriétés et de méthodes définies dans celle-ci.

Ajouter des fonctionnalités supplémentaires en créant de nouvelles propriétés et méthodes dans la classe dérivée.

Modifier le comportement standard d‟une classe d‟objet (classe mère) , en surchargeant certaines méthodes de la classe mère dans la classe dérivée.

Classe fille – Classe Parente

21/03/2013 A.ELmagri 45

Classe Mére

class ClasseA {

public int dataA;

public int MethodeA1() {

// coprs de la méthode

}

//Méthode surchargeable

public virtual int MethodeA2() {

/*coprs de la méthode */

}

}

Classe Fille

Class ClassB : ClassA{

public int Dtab ;

/* Redéfinition de la methodeA2 */

public override int MethodeA2(){ //code de la méthode

}

public int MethodeB1(){

//coprs de la méthode

}

}

Classe Fille /Classe Parente :

21/03/2013 A.ELmagri 46

Dans l‟exemple précédent :

ClasseA est la classe parente.

ClasseB est une classe dérivée de la classe ClasseA.

dataA est une propriété de la classe ClasseA. Par héritage, dataA est aussi une propriété de la classe ClasseB.

dtab est une propriété de la classe ClasseB (mais pas de ClasseA).

MethodeA1 est une méthode de la classe ClasseA. Par héritage, c'est aussi une méthode de la classe ClasseB.

MethodeB1 est une méthode de la classe ClasseB (mais pas de ClasseA).

MethodeA2 est une méthode des classes ClasseA et ClasseB.

Dans la classe A, MethodeA2() est déclarée virtual car elle est surchargeable dans la classe B

Dans la classe B, MethodeA2 est déclarée override car elle remplace la méthode de la classe A

Le mot clef Protected

21/03/2013 A.ELmagri 47

Même si les classes Enseignant et Salarie sont très proches de la classe Personne, le fait que les champs définis dans Personne le soit avec le mot clef private les oblige à utiliser les propriétés pour accéder.

Il existe un autre mot clef permettant l‟accés des champs d‟une classe à ses classes filles : protected.

Cela reviendrait à définir la classe Personne de la manière suivante :

public class Personne

{//Champs

protected string nom;

protected string prenom;

protected int age;

protected int telephone;

… }

Retenez surtout que protected permet l‟accès au champs uniquement aux classes-filles de Personne,

Constructeurs

21/03/2013 A.ELmagri 48

Contrairement aux méthodes, champs et propriétés, une classe fille n‟hérite pas des constructeur de sa classe mère.

Les constructeurs doivent donc être redéfinis. On peut cependant faire appel aux constructeurs de la classe mère:

public Enseignant(string nom, string prenom, int age, int tel,

int matricule, string etablissement) :base(nom, prenom, age, tel)

{ this. matricule= matricule;

this.etablissement = etablissement ;

}

Le mot clef base appelle le constructeur correspondant de la classe Personne.

Si l‟appel par le mot clef base est absent, alors le compilateur va se tourner vers un constructeur sans paramètre de Personne, (qui doit être préalablement définis) et renverra une erreur si ce constructeur n‟existe pas.

Retenez bien qu‟un objet Enseignant est aussi une Personne et doit donc être instancié comme une Personne avant de pouvoir être déclaré comme un Enseignant.

Méthodes

21/03/2013 A.ELmagri 49

Certaines méthodes d‟une classe mère peuvent ne plus être adaptée à sa/ses classe(s) fille(s). Il faut alors redéfinir la méthode en question.

Par exemple, la méthode AfficherPersonne() de la classe Personne ne permet pas de rendre compte de l‟ensemble des informations présentes dans la classe Enseignant.

Il faut donc la compléter de la manière suivante :

public void AfficherPersonne() {

string s = base.AfficherPersonne() + "," + this.matricule + "," + this.etablissement;

Console.WriteLine(s);

}

On aurait tout aussi bien écrire cette méthode de la façon suivante :

public void AfficherPersonne() {

string s = this.prenom + "," + this.nom + ",« + this.age + "," + this.tel + "," + this.matricule+ "," + this.etablissement ;

Console.WriteLine(s);

}

Classe abstraite(1)

21/03/2013 A.ELmagri 50

Comment implémenter les méthodes périmètre() et surface() dans la classe Forme ?

Les deux méthodes ne peuvent pas être implémentés dans la déclaration de la classe Forme. Car La formule de calcul change d‟une forme à l‟autre !!

Donc faut juste déclarer

les signatures de 2 méthodes dans

la classe Forme de la façon suivantes:

abstract public double Calcul_surface();

abstract Public double Calcul_Perim();

Les 2 méthodes seront par la suite

implémentées dans chaque classe fille

De façons différentes.

Classe abstraite(2)

21/03/2013 A.ELmagri 51

On dit que la classe Forme est une classe Abstraite, car elle

contient au moins une méthode abstraite.

Une classe abstraite ne peut pas être instanciée !

Les méthodes abstraites doivent obligatoirement être implémentés

dans les sous classes de la classe abstraite.

abstract public Class Form {

private string nom;

public Forme (string nom) {

this.nom = nom; }

abstract public double Calcul_perim();

public void dessiner() {

/*corps de la méthode */

}

}

Classe abstraite (3)

21/03/2013 A.ELmagri 52

La classe fille Cercle:

Public Class Cercle : Form {

private double rayon;

/*constructeur */

public Cercle (double rayon) : base(nom) {

this.rayon = rayon; }

/* implémentation de la méthode abstraite */

public double calcul_perim() {

return 2*Double.PI*this.rayon;

}

}

La classe fille Rectangle:

Public Class Rectangle: Form {

private double long;

private double large;

/*constructeur */

public rectangle (double long, double

large) : base(nom) {

this.long = long;

this.large = large;

}

/* implémentation de la méthode abstraite

*/

public double calcul_perim() {

return 2*(large + long) ;

}

}

La méthode ToString()(1)

21/03/2013 A.ELmagri 53

La méthode ToString est une méthode héritée de la super-classe

Object , Le prototype de la méthode ToString est le suivant :

public String ToString() ;

la méthode ToString: permet de convertir un objet de type classe en

String.

Exemple :

Class Rectangle {

private int largeur ;

private int longueur ;

public Rectangle(){ }

public Rectangle(int largeur , int longueur){

this.largeur=largeur ;

this.longueur=longueur ; }

…..}

Public static void Main(string[]args){

Rectangle r=new Rectangle(3,4) ;

Console.WriteLine(“r= ”+ r);

/* faux, impossible d’afficher l’objet r,

parce qu’on a pas surchargé la fonction

ToString dans la classe Rectangle */ }

La méthode ToString() (2)

21/03/2013 A.ELmagri 54

Pour remédier à ce problème, on doit surcharger ( redéfinir) la fonction ToString dans la classe Rectangle.

La classe Rectangle après modification :

Class Rectangle{

Private int largeur ;

Private int longueur ;

/* les constructeurs … */

/* La méthode ToString */

Public override String ToString(){

Return (“(”+ this.largeur

+ ”,” + this.longueur + ”)”); }

}

Public static void Main(string[]args){

Rectangle r = new Rectangle(3,4) ;

Console.WriteLine(“r= ”+ r); // c’est OK, et ça va afficher (3,4) }

La méthode Equals()

21/03/2013

A.ELmagri

55

Cette méthode doit répondre VRAI si deux instances sont rigoureusement égales.

De même que la méthode ToString La méthode Equals est une méthode virtual héritée de la classe Object, pour qu‟on puisse l‟utiliser dans n‟importe quelle classe on doit la surcharger.

Class Rectangle{

Private int largeur ;

Private int longueur ;

//le constructeur de recopie

Public Rectangle(Rectangle

rec){ This.largeur=rec.largeur ;

This.longueur=rec.longueur ;}

}

Public static void Main(string[]args){

Rectangle r1=new Rectangle(3,4) ;

Rectangle r2=new Rectangle(r1) ;

Boolean a= (r1==r2); /*ça va générer

erreur parce qu’on peut pas comparer

Deux objets en utilisant l’opérateur «

== » */ }

A.ELmagri

Classe Sealed

21/03/2013 A.ELmagri 56

Une classe Sealed : c‟est une classe dont on ne peut dériver ( ne peut pas être une classe mère).

C# permet de spécifier qu‟une classe ne peut en aucun cas être une classe de base. C‟est-à-dire aucune classe ne peut dériver de celle-ci. Pour cette raison, elle ne peut pas également être une classe abstraite.

Il suffit de mettre le mot clé sealed devant la déclaration de la classe

Ce type de classe ne peut avoir de méthodes abstraites

(abstract) ou de membres protégés (protected) car aucune classe dérivée ne pourra être créée pour les implémenter / y accéder.

Interface

21/03/2013 A.ELmagri 57

Lorsqu'une classe est déclarée en abstract et que toutes ses méthodes sont déclarées en abstract, on appelle en C# une telle classe une Interface.

Une interface ne doit contenir aucun champ ou attribut.

Une interface doit contenir des méthodes non implémentées.

Une interface est héritable.

Pour pouvoir construire un objet à partir d'une interface, il faut définir une classe non abstraite implémentant toutes les méthodes de l'interface.

Syntaxe :

interface < nom de l'interface > {

< corps des déclarations : méthodes, …>

}

Interface : Exemple

21/03/2013 A.ELmagri 58

interface Ivehicule {

/* Signatures de méthodes de l’interface*/

void Demarrer( );

void RpartirPassager( );

void PeriodiciteMaintenance( );

}

Les interfaces et l'héritage multiple

Avec l'héritage multiple, une classe peut hériter en même temps

de plusieurs super classes. Ce mécanisme n'existe pas en c#.

Les interfaces permettent de mettre en oeuvre un mécanisme

de remplacement.

Plusieurs interfaces peuvent être implémentées dans une même

classe.

21/03/2013 5

9

class nomClasse : Interface1, Interface2, ...{

//Implementer ici les méthodes des interfaces

}

A.ELmagri

Exemple:

21/03/2013 6

0

public class C : IA, IB {

double b;

double a;

public double somme() {

return a+b;

}

public double TrouverMax() {

double max ;

if (a ) max = a; else max = b;

return max;

}

Public interface IA{

double CalculerSomme(); }

Public interface IB{

double TrouverMax(); }

Les interfaces et l'héritage multiple

A.ELmagri

21/03/2013 A.ELmagri 61

IV. Polymorphisme

Polymorphisme ?

21/03/2013 A.ELmagri 62

Le polymorphisme est un mécanisme

via lequel un objet de la classe mère

peut prendre plus d'une forme (de ses

classes filles).

Exemple 1 :

Personne x;

Personne cl = new

Personne("Ali",42 );

Salarie sal = New Salarie("Ahmed",

23, 3000);

x = cl;

Console.WriteLine(x.ToString());

x = sal;

Console.WriteLine(x.ToString());

Par exemple, si vous avez une classe de base nommée Personne, une référence de type Personne peut être utilisé pour contenir un objet de n'importe laquelle de ses classes dérivées ( Salarie, Enseignant ..).

Quand vous appelez une méthode à partir de votre objet, le système déterminera automatiquement le type de l'objet afin d'appeler la méthode appropriée.

21/03/2013 A.ELmagri 63

Exemple2:

/*definir un tableau de vehicules (classe mere) */

Vehicule ve = new Vehicule [3];

/* ici chaque objet de tableau ve prend une forme (de classes

filles )*/

Ve[0] = new Voiture (….);

Ve[1] = new Camion (…);

Ve[2] = new Bus (…);

21/03/2013 A.ELmagri 64

La Classe String

21/03/2013 A.ELmagri 65

System.String est une classe fondamentale de .NET. Elle est

exclusivement conçue pour stocker des chaînes de caractères

et met à disposition du programmeur un grand nombre

d'opérations de traitement des chaînes

string (avec s minuscule) représente un raccourci vers le type

String (S majuscule)

String s = new String(“chaine");

// Equivaut à

string s = “chaine";

21/03/2013 A.ELmagri 66

La concaténation :

string msg1 = "Hello";

string msg2 = " World";

msg2 = String.Concat(msg1, msg2);

//équivaut à

msg2 += msg1;

La comparaison :

string s1 = "hello";

string s2 = "hello";

bool c1 = s1.Equals(s2);

//équivaut à

bool c1 = (s1 == s2);

Taille d‟une chaine string str = "MaChaine"

Console.Write(str.length); 8

Remplacer une chaine

Console.Write(str.replace(« Ma », «

Ta »));

TaChaine

Méthodes de String

21/03/2013 A.ELmagri 67

Méthodes de String (suite)

21/03/2013 A.ELmagri 68

Exemple

21/03/2013 A.ELmagri 69

public class string1{

// une classe de démonstration

public static void Main(){

string uneChaine="l'oiseau vole au-dessus des nuages";

affiche("uneChaine="+uneChaine);

affiche("uneChaine.Length="+uneChaine.Length);

affiche("chaine[10]="+uneChaine[10]);

affiche("uneChaine.IndexOf(\"vole\")="+uneChaine.IndexOf("vole"));

affiche("uneChaine.IndexOf(\"x\")="+uneChaine.IndexOf("x"));

affiche("uneChaine.LastIndexOf('a')="+uneChaine.LastIndexOf('a'));

affiche("uneChaine.LastIndexOf('x')="+uneChaine.LastIndexOf('x'));

affiche("uneChaine.Substring(4,7)="+uneChaine.Substring(4,7));

affiche("uneChaine.ToUpper()="+uneChaine.ToUpper());

affiche("uneChaine.ToLower()="+uneChaine.ToLower());

affiche("uneChaine.Replace('a','A')="+uneChaine.Replace('a','A'));

string[] champs=uneChaine.Split(null);

for (int i=0;i<champs.Length;i++){

affiche("champs["+i+"]=["+champs[i]+"]");

}

affiche("Join(\":\",champs)="+System.String.Join(":",champs));

affiche("(\" abc \").Trim() =["+" abc ".Trim()+"]");

}

public static void affiche(String msg){

// affiche msg

Console.Out.WriteLine(msg);

}

}

Après exécution de l’exemple précèdent:

21/03/2013 A.ELmagri 70

uneChaine=l'oiseau vole au-dessus des nuages

uneChaine.Length=34

chaine[10]=o

uneChaine.IndexOf("vole")=9

uneChaine.IndexOf("x")=-1

uneChaine.LastIndexOf('a')=30

uneChaine.LastIndexOf('x')=-1

uneChaine.Substring(4,7)=seau vo

uneChaine.ToUpper()=L'OISEAU VOLE AU-DESSUS DES NUAGES

uneChaine.ToLower()=l'oiseau vole au-dessus des nuages

uneChaine.Replace('a','A')=l'oiseAu vole Au-dessus des nuAges

champs[0]=[l'oiseau]

champs[1]=[vole]

champs[2]=[au-dessus]

champs[3]=[des]

champs[4]=[nuages]

Join(":",champs)=l'oiseau:vole:au-dessus:des:nuages

(" abc ").Trim()=[abc]

Exercice

21/03/2013 A.ELmagri 71

Ecrire un programme qui supprime toutes les

occurrences d‟un caractère C dans une chaine Str.

Inverser une chaine de caractères.

Remplacer le premier caractère de chaque mot

dans une phrase par le majuscule.

21/03/2013 A.ELmagri 72

La classe Regex

La classe Regex

21/03/2013 A.ELmagri 73

La classe Regex permet de tester le format d'une chaîne de

caractères.

Ainsi on peut vérifier qu'une chaîne représentant une date est

bien au format jj/mm/aa.

On utilise pour cela un modèle et on compare la chaîne à ce

modèle. Ainsi dans cet exemple, j m et a doivent être des

chiffres. Le modèle d'un format de date valide est alors

"\d\d/\d\d/\d\d" où le symbole \d désigne un chiffre

Le symbole \d

21/03/2013 A.ELmagri 74

Considérons quelques exemples autour du symbole \d qui représente

1 chiffre :

Modele Signification

\d

0 ou un chiffre

\d* 0 ou davantage de chiffres

\d+ 1 ou davantage de chiffres

\d{2} 2 chiffres

\d{3,} au moins 3 chiffres

\d{5,7} entre 5 et 7 chiffres

Exemples de modèles:

21/03/2013 A.ELmagri 75

une date au format jj/mm/aa : \d{2}/\d{2}/\d{2}

une heure au format hh:mm:ss: \d{2}:\d{2}:\d{2}

IsMatch

21/03/2013 A.ELmagri 76

Un objet de type Regex se construit de la façon suivante :

construit un objet à partir d'un modèle passé en paramètre (pattern)

Une fois le modèle construit, on peut la comparer à des chaînes de caractères avec la méthode IsMatch :

Qui retourne vrai si la chaîne input correspond au modèle créé.

/*constructeur */

public Regex(string pattern)

public bool IsMatch(string input)

Exemple: Format d’une date

21/03/2013 A.ELmagri 77

static void Main(string[] args)

{// une expression régulière modèle

string modèle1 =

@"\d{2}/\d{2}/\d{2}";

Regex regex1=new

Regex(modèle1);

// comparer un exemplaire au modèle

string exmple=" 11/02/99 ";

if (regex1.IsMatch(exmple)){

Console.WriteLine("["+exmple + "] correspond au modèle ["+modèle1+"]");

} else {

Console.WriteLine("[" + exmple + "] ne correspond pas au modèle [" + modèle1 + "]");

} Console.ReadKey();

}

Ne pas oublier : using System.text.RegularExpressions

III. Les Classes de collections

21/03/2013 78 A.ELmagri

Les tableaux statiques (1)

21/03/2013 A.ELmagri 79

Les tableaux contiennent des éléments, chacun d‟eux étant repéré par son

indice.

En C#, il existe une manière très simple de créer des tableaux «classiques

», sans faire référence aux classes Collections.

/* déclaration*/

String[] aStr=new string[5] ;

aStr[0]=”Ahmed”;

aStr[1]=”Farid”;

aStr[2]=”Ali”;

aStr[3]=”Ibrahim”;

aStr[4]= ”Mohamed”;

//Déclaration

Salarie[] sal=new Salarie[5] ;

Salarie[0]=new Salarie(16,4,2, "toto ",8765) ;

Salarie[1]=new Salarie(8,5,2, "Ali ",6543) ;

Salarie[2]=new Salarie(32,4,2, " Farid ",2075) ;

Salarie[3]=new Salarie(20,5,3, "Ahmed ",2165) ;

Salarie[4]=new Salarie(9,65,2, "Mohamed ",765) ;

21/03/2013 A.ELmagri 80

Le problème de ce type de tableau réside en deux points :

Tous les éléments du tableau ont le même type.

Le nombre des éléments du tableau est connu au moment de la

déclaration.

Pour afficher tous les éléments d‟un tableau statique tab :

Ce programme stocke à chaque fois la valeur d‟un élément du tableau tab dans la

variable intVal , puis affiche cette dernière.

Le mot-clef foreach permet de parcourir des objets. Sa syntaxe est :

Les tableaux statiques (2)

foreach(intVal in tab){

Console.WriteLine(intVal) ; }

foreach (typeDeLelement element in collectionDelements)

{/* Code utilisant l„element.*/ }

ArrayList (1)

21/03/2013 A.ELmagri 81

La classe ArrayList: est un tableau dynamique auquel on peut rajouter

ou insérer des éléments et en supprimer.

Il faut utiliser le namespace: System.Collections

Using System.Collections ;

…..

/*declaration d‟un tableau dynamique*/

ArrayList maListe = new ArrayList() ;

/* Ajouter un element au tableau*/

maListe.add(1) ;

maListe.add(80) ;

/* Supprimer un element au tableau*/

maListe.remove(1);

//Afficher le tableau maListe :

foreach (int val in maListe ) {

Console.WriteLine(val); }

// Accès à un élément

Console.WriteLine(“deuxiéme

element ”+ maListe [1]);

ArrayList (2)

21/03/2013 A.ELmagri 82

Quelques méthodes de la classe ArrayList

La classe Hachtable

21/03/2013 A.ELmagri 83

Un objet de type Hashtable: représente une collection

de pairs (Key, value). La clé est le hashcode : l’identifiant de l’ élément.

Valeur : c’est la valeur stockée dans l’élément.

Exemple: /* Instancier un objet de type Hashtable */

Hashtable dict = new Hashtable() ;

/* Insérer un élément par add() */

dict.add(1, « toto ») ;

dict.add(2, « titi »);

/* Nombre d‟élément du dictionnaire */

int nbr=dict.Count() ;

/* Supprimer un élément en fonction de sa clé (hashcode) */

dict.Remove(clé) ;

/* vider le dictionnaire par Clear() */

dict.Clear() ;

//Parcourir le dictionnaire

for (int i = 0; i < dict.Count; i++) ou

foreach(int i in dict.Keys);

foreach(string s in dict.values);

NB : Le dictionnaire

Hashtable ne trie pas les

éléments, et pour avoir un

dictionnaire trié dans l’ordre

croissant en fonction de la clé de

ses éléments, on doit utiliser la

classe SortedList ou lieu de la

classe Hashtable

La classe SortedList (1)

21/03/2013 A.ELmagri 84

SortedList est un dictionnaire qui garantit que les clés soient

rangées de façon ascendante (dans l‟ordre croissant).

Exemple : static void Main(){

/* Instancier un objet de type SotedList */

SortedList s =new SortedList() ;

/* Ajouter des elements dans s */

s.add(32,"Java");

s.add(21, "C#");

s.add(7, "VB.net");

s.add(49, "C++");

/* afficher le dictionnaire s */

For(int i=0 ; i<s.count ; i++){

Console.WriteLine("clé ="+

s.GetKey(i) + " , valeur= "+

s.GetByIndex(i)); }

La classe SortedList (2)

21/03/2013 A.ELmagri 85

Voici quelques méthodes qui permettent de manipuler un

dictionnaire de type SortedList.

Exemple simple:

21/03/2013 A.ELmagri 86

static void Main(string[] args)

{

Hashtable hash = new Hashtable();

/* Alimenter le dictionnaire hash*/

hash.Add(3, "Casa");

hash.Add(2, "Rabat");

hash.Add(4, "Sale");

SortedList sorted = new SortedList();

/* Alimenter le dictionnaire maListeSorted*/

sorted.Add(1, "Casa");

sorted.Add(2, "Rabat");

sorted.Add(3, "Sale");

ArrayList liste = new ArrayList();

/* Alimenter la liste */

liste.Add("Casa"); liste.Add("Rabat");

liste.Add("Sale");

foreach (string ville in liste)

Console.WriteLine("la ville est :

"+ville);

/* affichage de sortedList est trie */

foreach (DictionaryEntry ville in sorted)

Console.WriteLine("ville key : " +

ville.Key + "ville value : "

+ville.Value);

/*l'affichage de hash n est pas trie */

foreach (DictionaryEntry ville in hash)

Console.WriteLine("ville key (hash) :

" + ville.Key + "Ville value (hash) :"

+ ville.Value);

Console.ReadKey();

}

Les collections génériques:

21/03/2013 A.ELmagri 87

List<T>

HashSet<T>

LinkedList<T>

Dictionary<TKey,TValue>

SortedList <TKey,TValue>

List<T> La classe System.Collections.Generic.List<T> permet

d'implémenter des collections d'objets de type T dont la taille

varie au cours de l'exécution du programme.

Un objet de type List<T> se manipule presque comme un

tableau. Ainsi l'élément i d'une liste Liste est-il noté Liste[i].

Pour un objet List<T> ou T est une classe, la liste stocke là

encore les références des objets de type T.

21/03/2013 8

8

A.ELmagri

List<T>

21/03/2013 8

9

using System.Collections;

public static void Main(string[] args)

{

// creer 4 personnes

personne p1 = new personne("nom1", "prenom1", 23,

"Ville1");

personne p2 = new personne("nom2", "prenom2", 24,

"Ville2");

personne p3 = new personne("nom3", "prenom3", 25,

"Ville3");

personne p4 = new personne("nom4", "prenom4", 30,

"Ville4");

// creer la liste

List<personne> list = new List<personne>();

// remplir la liste

list.Add(p1);

list.Add(p2);

list.Add(p3);

list.Add(p4);

// parcourir la liste 1 ere méthode

for (int i = 0; i < list.Count; i++)

{

Console.WriteLine(list[i].ToString());

}

// parcourir la liste 2eme méthode

foreach (personne p in list)

{

Console.WriteLine(p.ToString());

}

Console.ReadLine();

}

A.ELmagri

HashSet<T>

21/03/2013 9

0

using System.Collections;

public static void Main(string[] args)

{

// creer 4 personnes

personne p1 = new personne("nom1", "prenom1", 23, "Ville1");

personne p2 = new personne("nom2", "prenom2", 24, "Ville2");

personne p3 = new personne("nom3", "prenom3", 25, "Ville3");

personne p4 = new personne("nom4", "prenom4", 30, "Ville4");

// creer la liste

HashSet <personne> list = new Hashset <personne>();

// remplir la liste

list.Add(p1);

list.Add(p2);

list.Add(p3);

list.Add(p4);

// parcourir la liste 2eme méthode

foreach (personne p in list)

{

Console.WriteLine(p.ToString());

}

Console.ReadLine();

}

A.ELmagri

LinkedList<T>

21/03/2013 9

1

using System.Collections;

public static void Main(string[] args)

{

// creer 4 personnes

personne p1 = new personne("nom1", "prenom1", 23, "Ville1");

personne p2 = new personne("nom2", "prenom2", 24, "Ville2");

personne p3 = new personne("nom3", "prenom3", 25, "Ville3");

personne p4 = new personne("nom4", "prenom4", 30, "Ville4");

// creer la liste

LinkedList <personne> list =

new LinkedList <personne>();

// remplir la liste

list.AddLast(p1);

list.AddLast(p2);

list.AddLast(p3);

list.AddLast(p4);

// parcourir la liste

foreach (personne p in list)

{

Console.WriteLine(p.ToString());

}

Console.ReadLine();

}

A.ELmagri

Dictionary<TKey,TValue>

21/03/2013 9

2

using System.Collections;

public static void Main(string[] args)

{

// creer 4 personnes

personne p1 = new personne("nom1", "prenom1", 23, "Ville1");

personne p2 = new personne("nom2", "prenom2", 24, "Ville2");

personne p3 = new personne("nom3", "prenom3", 25, "Ville3");

personne p4 = new personne("nom4", "prenom4", 30, "Ville4");

// creer le dictionnaire

Dictionary<string, personne> dic = new

Dictionary<String, personne>();

// remplir le dictionnaire

dic.Add(p1.Nom,p1);

dic.Add(p2.Nom, p2);

dic.Add(p3.Nom, p3);

dic.Add(p4.Nom, p4);

// pour afficher les clés et les valeurs

foreach (String s in dic.Keys)

{

Console.WriteLine("la clé est : "

+s

+" la valeur est :"+

dic[s].ToString()());

}

// pour afficher les valeurs

foreach (personne p in dic.Values)

{

Console.WriteLine(p.ToString()());

}

A.ELmagri

SortedList <TKey,TValue>

21/03/2013 9

3

using System.Collections;

public static void Main(string[] args)

{

// creer 4 personnes

personne p1 = new personne("nom1", "prenom1", 23, "Ville1");

personne p2 = new personne("nom2", "prenom2", 24, "Ville2");

personne p3 = new personne("nom3", "prenom3", 25, "Ville3");

personne p4 = new personne("nom4", "prenom4", 30, "Ville4");

// creer le Hashtable

SortedList<string, personne> dic = new

SortedList<string, personne> ();

// remplir le dictionnaire

dic.Add(p1.Nom,p1);

dic.Add(p2.Nom, p2);

dic.Add(p3.Nom, p3);

dic.Add(p4.Nom, p4);

// pour afficher les clés

foreach (String s in dic.Keys)

{

Console.WriteLine("la clé est : " +s) ;

}

// pour afficher les valeurs

foreach (personne p in dic.Values)

{

Console.WriteLine(p.ToString());

}

A.ELmagri

Exercice Créer la classe personne qui contient la code, le nom , le prenom , et l‟age.

Créer les constructeurs et les propriétés

Ecrire la methode getInfo();

Créer une liste qui stocke les personnes

Créer la méthode ajouter(personne) qui ajoute une personne à la liste.

Créer la méthode modifier_nom (code, nom) qui modifie le nom d‟une personne.

Créer la méthode supprimer (nom) qui supprime une personne de la liste.

Créer la méthode chercher(code) qui cherche une personne connaissant son code.

Créer la méthode affichage() qui liste toutes les personnes.

Créer la méthode compter() qui return le nombre des personnes stockées.

créer une fonction categories() qui affiche la catégorie de chaque personne ( « p » si son age <18 , « j » si son age est entre 19 est 35 , et « g » si son age > 35.

Ecrire un menu pour appeler ces fonctions.

21/03/2013 9

4

A.ELmagri

Solution

21/03/2013 9

5

class personne

{

int code;

String nom;

String prenom;

int age;

// les propriétés

public int Code

{

get { return code; }

set { code = value; }

}

public String Prenom

{

get { return prenom; }

set { prenom = value; }

}

public int Age

{

get { return age; }

set { age = value; }

}

public String Nom

{

get { return nom; }

set { nom = value; }

}

// Constructeurs

public personne() { }

public personne(String nom, String prenom, int

age, int code)

{

this.nom = nom;

this.prenom = prenom;

this.age = age;

this.code = code;

} A.ELmagri

21/03/2013 9

6

public String getinfo()

{ return " Je m’appelle " + nom + " -- " + Prenom + " J’ai " + Age

+ " an j'ai le code " + code;

}

// déclaration de la liste des personne

static List<personne> lis = new List<personne>();

static public void ajouter(personne p)

{ lis.Add(p);

}

static public void modifier_nom(int c ,String n)

{

foreach (personne p in lis)

{

if (p.code==c)

{

p.nom = n;

}

}

}

A.ELmagri

21/03/2013 9

7

static public Personne chercher(int code)

{Persone pr = null;

foreach (personne p in lis)

{

if (p.code == code)

{

pr = p; break;

}

} return pr;

}

static public void supprimer( String n)

{

foreach (personne p in lis)

{

if (p.nom.Equals(n))

{

lis.Remove(p);

break;

}

}

}

A.ELmagri

21/03/2013 9

8

static public void affichage()

{

foreach (personne p in lis)

{

Console.WriteLine(p.getinfo());

}

}

static public int compter()

{

return lis.Count;

}

static public void categories()

{

foreach (personne p in lis)

{

if(p.age<= 18)

Console.WriteLine("la catégorie de "+p.nom+ " est :P" );

if (p.age >= 19 && p.age<=35)

Console.WriteLine("la catégorie de " + p.nom + " est :J");

if (p.age >= 36)

Console.WriteLine("la catégorie de " + p.nom + " est :G");

}

}

}

A.ELmagri

21/03/2013 9

9

public class test

{

public static void Main(string[] args)

{

int c;

do

{

Console.WriteLine("1- pour ajouter");

Console.WriteLine("2- pour afficher");

Console.WriteLine("3- pour modifier");

Console.WriteLine("4- pour supprimer");

Console.WriteLine("5- pour rechercher");

Console.WriteLine("6- pour afficher la gategorie");

Console.WriteLine("7- pour compter");

Console.WriteLine("8- pour quitter");

c = int.Parse(Console.ReadLine());

A.ELmagri

21/03/2013 1

0

0

switch (c)

{

case 1:

{

Console.WriteLine("donner le nom , le prenom, l'age

et le code");

String n = Console.ReadLine();

String pr = Console.ReadLine();

int a = int.Parse(Console.ReadLine());

int co = int.Parse(Console.ReadLine());

personne p = new personne(n, pr, a, co);

personne.ajouter(p);

break;

}

case 2: personne.affichage(); break;

case 3:

{

Console.WriteLine("entrer le code à modifier");

int co = int.Parse(Console.ReadLine());

Console.WriteLine("donner le nouveau nom");

String n = Console.ReadLine();

personne.modifier_nom(co, n); break;

}

A.ELmagri

21/03/2013 1

0

1

case 4:

{

Console.WriteLine("entrer le nom à supprimer");

String n = Console.ReadLine();

personne.supprimer(n); break;

}

case 5:

{

Console.WriteLine("entrer le code à chercher");

int n = int.Parse(Console.ReadLine());

personne.chercher(n); break;

}

case 6: personne.categories(); break;

case 7: Console.WriteLine("le nombre des personnes est :" +

personne.compter()); break;

}

} while (c != 8);

Console.ReadLine();

}

}

}

A.ELmagri

V. Gestion des Exceptions

21/03/2013 102 A.ELmagri

Problème

21/03/2013 1

0

3

class Program

{

static void Main(string[] args)

{

int a=10, b=0, c;

Console.WriteLine("Avant division");

c = a/b;

Console.WriteLine("Après division, c

vaut " + c);

}

}

Essayons dans ce premier exemple de voir l'effet des erreurs courantes sur le

fonctionnement du programme suivant:

A.ELmagri

Problème

21/03/2013 1

0

4

Essayons dans ce premier exemple de voir l'effet des erreurs courantes sur le

fonctionnement du programme

A.ELmagri

Une première solution

21/03/2013 1

0

5

public class Program

{

public static void Main(string[] args)

{

int a = 10, b = 0, c;

Console.WriteLine("Avant division");

if (b == 0)

Console.WriteLine("Division par zéro");

else

{ c = a / b;

Console.WriteLine("Après division, c vaut " + c);

}

Console.ReadLine();

}

}

Pour ne pas avoir de problème il suffit de tester les valeurs entrées :

Le problème posé par cette solution est une augmentation des lignes de code et une

complication du programme.

De plus, si l'on oublie de tester une valeur, il y aura arrêt brutal du programme (bugs de

programmes).

A.ELmagri

Une 2éme Solution : Try ..Catch

21/03/2013 1

0

6

static void Main(string[] args)

{

try

{

int a = 10, b = 0, c;

Console.WriteLine("Avant division");

c = a / b;

Console.WriteLine("Après division, c vaut " + c);

}

catch (DivideByZeroException ex)

{

Console.WriteLine(ex.Message);

}

}

A.ELmagri

Alors, c’est quoi une exception?

21/03/2013 A.ELmagri 107

Lorsqu'un problème survient au cours de l'exécution d'un

programme C#, une exception se produit.

Les exceptions interrompent le flux du programme en cours et, si

rien n'est fait, le programme cesse tout simplement de s'exécuter.

Une exception constitue souvent un moyen pratique de quitter une

section de code qui ne s'applique plus, ou de signaler qu'une

méthode a échoué ou ne respecte pas certaines règles de gestion.

Exemples: affecter une valeur int à un string, un nombre divisé

par zéro, ou entrée inattendue (un utilisateur sélectionne un

fichier inexistant).

Capture d’une exception :

21/03/2013 A.ELmagri 108

C# fournit plusieurs mots clés: try, catch et finally qui permettent aux programmes de détecter les exceptions, de les gérer et de poursuivre l'exécution.

Le bloc try: contient le code qui effectue les opérations normales du programme, mais qui risque de rencontrer des erreurs plus ou moins inatendues.

Le bloc catch: contient le code de traitement des erreurs qui sont apparues lors de l'exécution du programme.

Le bloc finally: contient le code que vous voulez impérativement exécuter après le bloc try ou catch. Ce bloc est exécuté qu'une exceptions soit levée ou pas !

Try {//code qui peut générer des exception}

Catch ( TypeException1 e){//code exécuté si une Exception1 est détectée}

Catch ( TypeException2 e){//code exécuté si une Exception2 est détectée}

Finally {//code exécuté à la fin tout le temps }

Comment cela fonctionne ?

21/03/2013 A.ELmagri 109

Le schéma de fonctionnement est le suivant :

1- Le flux d'exécution entre dans le bloc try

2- S'il n'y a pas d'erreur, on passe directement à l'étape 4

3- En cas d'erreur, l'exécution se poursuit dans le

bloc catch où les erreurs sont gérées

4- Le bloc finally est exécuté

Exemple : Try ..Catch

21/03/2013 A.ELmagri 110

Dans cet exemple, un calcul crée une exception de division par zéro, qui est

ensuite interceptée. Sans les blocs try et catch, ce programme échouerait.

class ProgramTryCatch {

static void Main() {

int x=0, y=0;

try { /* bloc qui genere l‟exception */

x = 10 / y; }

/*bloc qui gere l exception */

catch (System.DivideByZeroException) {

System.Console.WriteLine(« impossible de

diviser par 0"); }

} /* le bloc finally est facultatif */

}

Levée d’une exception

21/03/2013 A.ELmagri 111

Alors comment cela fonctionne-t-il ? Comment le runtime

sait-il qu'il doit aller dans un bloc catch (ou pas) en cas

d'erreur ?

Lorsqu'une erreur est détectée, le code lève une

exception : avec throw new Exception(),

Et c'est à ce moment là que l'exécution normale du

bloc try s'arrête pour passer dans le bloc catch approprié

: catch (Exception e) {… }

Exemple : de mot clé throw

21/03/2013 A.ELmagri 112

class ProgramThrow {

/* methode faire */

static void Faire(int x) {

if (x > 5) {

throw new ArgumentOutOfRangeException("X is too large");

} }

/* methode main*/

static void Main() {

try { Faire(10); }

catch (ArgumentOutOfRangeException ex) {

System.Console.WriteLine(ex.Message); }

}

}

le bloc finally a été ommis : celui est en effet facultatif.

Quelques classes d'exceptions

21/03/2013 A.ELmagri 113

Le Framework .Net offre beaucoup de classes gérant les exceptions

dont :

System.Exception

System.SystemException

System.ArgumentException

System.ArgumentNullException

System.OutOfRangeException

System.IO.FileNotFoundException

System.ApplicationException

Les relations d’héritage entres les différentes

Classes exceptions

Exemple:

21/03/2013 A.ELmagri 114

using System;

public class Program {

public static void Main() {

int nombre = 0;

bool quit = false;

while (!quit) {

Console.Write("Entrez un nombre : ");

string chaine = Console.ReadLine();

try { /* Code à risque : il se peut que l'utilisateur n'entre pas un nombre , que ce nombre ne soit pas un entier compris entre - 2 147 438 648 et + 2 147 438 647 */

nombre = Int32.Parse(chaine); quit = true; }

/* ici pour chaque type d’ exception on a fait un catch*/

catch (ArgumentExceptio argEx) { Console.WriteLine(argEx.Message); }

catch (FormatException formEx) { Console.WriteLine(formEx.Message); }

catch (OverflowException overEx) { Console.WriteLine(overEx.Message); } } } }

Créer sa propre exception

Et bien oui, c‟est possible!!

Prenons la classe Personne déjà créé.

Imposons la condition: Si l‟utilisateur saisit une valeur d‟âge <= 18 ou >= 60 , le système doit levé une exception

La solution consiste à créer une classe AgeException.

21/03/2013 1

1

5

public class AgeException : Exception

{

public AgeException(string msg): base(msg)

{

}

}

A.ELmagri

Utiliser l’exception crée

21/03/2013 1

1

6

//Dans le constructeur de la classe Personne

public Personne (String nom, int age)

{

//lever une exception si l‟age n est pas valide

if (age < 18 || age > 60) throw new AgeException("l'age doit etre entre 18 et

60");

else

{

this.nom = nom;

this.age = age;

}

}

A.ELmagri

Utiliser l’exception crée

21/03/2013 1

1

7

// Dans le setter

public int SetAge(int value)

{

//lever l exception si lage n est pa valide

if (value < 18 || value > 60) throw new AgeException("l'age doit etre

entre 18 et 60");

else

{

age = value;

}

}

}

A.ELmagri

La Sérialisation d’objet

21/03/2013 118 A.ELmagri

La sérialisation d’objet

La sérialisation (en anglais serialization) est un procédé qui

consiste à sauver l'état d'un objet sur le disque ou le réseau plutôt

que de le garder en mémoire.

On peut dire que l'objet est "aplatit" pour pouvoir le convertir

en un flux de données, que l'on peut transmettre à un autre objet

via la désérialisation

La sérialisation et la désérialisation se fait via des fichiers (binaire,

XML,…).

21/03/2013 1

1

9

A.ELmagri

Sérialiser un objet (XML)

On crée la classe personne , pour pouvoir stocker l‟objet dans un fichier il faut que celui-ci soi

sérializable.

21/03/2013 1

2

0

using System.IO;

using System.Xml.Serialization;

namespace test

{

[Serializable]

public class personne

{

public personne() { }

string nom;

public string Nom

{

get { return nom; }

set { nom = value; }

}

string prenom;

public string Prenom

{

get { return prenom; }

set { prenom = value; }

}

string telephone;

public string Telephone

{

get { return telephone; }

set { telephone = value; } }

A.ELmagri

Sérialiser un objet

21/03/2013 1

2

1

// list des personne

public static List<personne> carnet = new List<personne>();

// serialiser l'objet carnet :

public static void SauvegarderXML(string nomfichier)

{

FileStream f = File.Open(nomfichier, FileMode.OpenOrCreate);

XmlSerializer s = new XmlSerializer(typeof(List<personne>));

s.Serialize(f, carnet);

f.Close();

}

A.ELmagri

Sérialiser un objet

21/03/2013 1

2

2

// déserialiser l'objet carnet :

public static List<personne> ChargerXML(string nomfichier)

{

FileStream f = File.Open(nomfichier, FileMode.Open);

XmlSerializer s = new XmlSerializer(typeof(List<personne>));

List<personne> lis = (List<personne>)s.Deserialize(f);

f.Close();

return lis;

}

A.ELmagri

Sérialiser un objet

21/03/2013 1

2

3

public static void Main(string[] args)

{ personne p = new personne();

p.Nom = "aa";

p.Prenom = "fff";

p.Telephone = "12356";

// ajouter la personne à la liste

personne.carnet.Add(p);

// sauvgarder dans le fichier nommé test

personne.SauvegarderXML("test");

}

A.ELmagri

Sérialiser un objet

Résultat

21/03/2013 1

2

4

A.ELmagri

Désérialiser un objet

21/03/2013 1

2

5

public static void Main(string[] args)

{

// creer une liste et la remplir à partir du fichier

List<personne> k = personne.ChargerXML("test");

// parcourir la liste

foreach (personne s in k)

{

System.Console.WriteLine(s.Nom + " " +

s.Prenom + " " + s.Telephone);

}

A.ELmagri

DéSérialiser un objet

Résultat

21/03/2013 1

2

6

A.ELmagri

Sérialiser un objet (BIN) On travaille avec la même classe Personne déjà créé:

21/03/2013 1

2

7

Using System.IO;

Using System.Xml.Serialization;

using System.Runtime.Serialization;

using System.Runtime.Serialization.Formatters.Binary; namespace test

{

[Serializable]

public class personne

{

public personne() { }

string nom;

public string Nom

{

get { return nom; }

set { nom = value; }

}

string prenom;

public string Prenom

{

get { return prenom; }

set { prenom = value; }

}

string telephone;

public string Telephone

{

get { return telephone; }

set { telephone = value; } }

A.ELmagri

Sérialiser et déserialiser un objet (BIN)

21/03/2013 1

2

8

// serialiser l'objet carnet en binaire :

public static void SauvegarderBin(string nomfichier)

{

FileStream f = File.Open(nomfichier, FileMode.OpenOrCreate);

IFormatter s = new BinaryFormatter();

s.Serialize(f, carnet);

f.Close();

}

// déserialiser l'objet carnet en binaire :

public static List<personne> chargerBin(string nomfichier)

{

FileStream f = File.Open(nomfichier, FileMode.Open);

IFormatter s = new BinaryFormatter();

List<personne> lo = (List<personne>)s.Deserialize(f);

f.Close();

return lo;

}

A.ELmagri

Sérialiser et déserialiser un objet (BIN)

21/03/2013 1

2

9

public static void Main(string[] args) {

personne p = new personne();

p.Nom = "aa"; p.Prenom = "fff"; p.Telephone = "12356";

// Ajouter la personne à la liste

personne.carnet.Add(p);

// Sauvgarder dans le fichier nommé test

personne.SauvegarderBin("test");

// Creer une liste et la remplir à partir du fichier

List<personne> k = personne.chargerBin("test");

// Parcourir la liste

foreach (personne s in k)

{

System.Console.WriteLine(s.Nom + " " + s.Prenom + " " + s.Telephone);

} A.ELmagri

FI N

21/03/2013 130 A.ELmagri