cours poo c#
TRANSCRIPT
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 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 ;
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
}
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");
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
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 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
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.
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
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]);
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
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
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
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
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