102
R La program Propos Office de ROYAUME DU MAROC OFPPT ISGI LAAYOUNE 2014/2015 mmation orient (POO) sé par : Mohammed CHAKO la Formation Professionnelle et de la Prom tée objet OUJ motion du Travail

La POO

Embed Size (px)

DESCRIPTION

La Programmation Orientée Objet

Citation preview

ROYAUME DU MAROC

La programmation orientée objet

Proposé par : Mohammed CHAKOUJ

Office de la Formation Professionnelle et de la Promotion du Travail

ROYAUME DU MAROC

OFPPT ISGI LAAYOUNE

2014/2015

La programmation orientée objet

(POO)

Proposé par : Mohammed CHAKOUJ

Office de la Formation Professionnelle et de la Promotion du Travail

La programmation orientée objet

Proposé par : Mohammed CHAKOUJ

Office de la Formation Professionnelle et de la Promotion du Travail

Programmation orientée objet 1

M.CHAKOUJ

2

Programmation orientée objet M.CHAKOUJ

TABLE DES MATIERES :

Table des matières :……………………………………………………………………………………………………………………2

Chapitre 1 : Introduction à la POO ....................................................................................................................................... 6

Objectif du module : ......................................................................................................................................................... 6

I. Programmation orientée objet VS programmation structurée : ............................................................................. 6

II. Concepts de base de la Programmation Orientée Objet(POO) :............................................................................. 6

1-Définitions : ................................................................................................................................................................... 6

2-Les avantages de la POO : ......................................................................................................................................... 6

3-La notion d’objet : ..................................................................................................................................................... 7

4-La notion de classe : .................................................................................................................................................. 7

5-La notion d’encapsulation : ....................................................................................................................................... 8

6-Communication entre objets : .................................................................................................................................. 8

7-La notion d’abstraction : ........................................................................................................................................... 9

III. Le Langage C# : ..................................................................................................................................................... 9

TEST chapitre 1 : ............................................................................................................................................................... 10

Chapitre 2 : L’IDE Visual Studio 2010 et l’architecture du dotNet .................................................................................... 11

I. L’IDE Visual Studio de Microsoft : .......................................................................................................................... 11

II. Création du premier projet : .................................................................................................................................. 11

III. L’architecture de .NET Framework ..................................................................................................................... 14

TEST chapitre 2 : .............................................................................................................................................................. 16

Chapitre 3 C# : Notions de base ......................................................................................................................................... 17

I. Commentaires en C# : ............................................................................................................................................ 17

II. Les types de base : ................................................................................................................................................. 17

III. Identificateurs en C# .......................................................................................................................................... 19

IV. Opérations d’entrée/sortie ................................................................................................................................ 19

1. Affichages ........................................................................................................................................................... 19

2. Lecture de données saisies au clavier ................................................................................................................ 20

V. L’instruction if : ....................................................................................................................................................... 20

VI. L’instruction Switch : ......................................................................................................................................... 21

VII. Les boucles : ....................................................................................................................................................... 21

TP1 ..................................................................................................................................................................................... 23

Chapitre 4 : Notre première classe en C# .......................................................................................................................... 24

I. L’ajout d’une nouvelle classe à un projet: ............................................................................................................ 24

II. La portée des attributs et méthodes :.................................................................................................................... 25

III. Le mot clé this : .................................................................................................................................................. 26

IV. Le test de la classe personne : ............................................................................................................................ 26

3

Programmation orientée objet M.CHAKOUJ

V. L'opérateur new : ................................................................................................................................................... 27

VI. Constructeurs de classe...................................................................................................................................... 27

VII. La surcharge d’une méthode : ........................................................................................................................... 28

VIII. Le type objet est un type référence : ................................................................................................................. 29

IX. Passage de paramètres: ..................................................................................................................................... 30

1. Passage de paramètres par référence .................................................................................................................. 30

2. Passage de paramètres en sortie : le mot clé out .................................................................................................. 31

X. Tableaux statiques ................................................................................................................................................. 31

1. La classe Array : .................................................................................................................................................. 31

2. Syntaxe de déclaration et création d’un tableau: ............................................................................................. 33

a. Tableaux à une dimension ................................................................................................................................. 33

b. Tableau à deux dimensions : .............................................................................................................................. 33

3. Le parcours d’un tableau en lecture avec la boucle foreach : .......................................................................... 34

XI. Les chaines de caractères : la classe System.String........................................................................................... 36

XII. Les structures : ................................................................................................................................................... 38

XIII. Les énumérations................................................................................................................................................ 39

XIV. Les fichiers texte en C# : ..................................................................................................................................... 40

TP2 ..................................................................................................................................................................................... 43

Chapitre 5 : Accesseurs , Propriétés ,et membres static .................................................................................................. 46

I. Méthodes de lecture et d'écriture des attributs privés : ....................................................................................... 46

II. Les propriétés ......................................................................................................................................................... 47

III. Les méthodes et attributs de classe : le mot clé static ...................................................................................... 48

TP3 ..................................................................................................................................................................................... 52

Chapitre 6 : L’héritage et le polymorphisme ..................................................................................................................... 55

I. L’héritage ................................................................................................................................................................ 55

1. Définition : .......................................................................................................................................................... 55

2. Syntaxe : ............................................................................................................................................................. 55

3. Constructeurs et chaînage ................................................................................................................................. 57

4. Référence d'instance .......................................................................................................................................... 58

II. polymorphisme ...................................................................................................................................................... 58

1. Principe ............................................................................................................................................................... 59

2. Mise en place ..................................................................................................................................................... 59

3. Chainage des redéfinitions ................................................................................................................................. 59

TP4 ..................................................................................................................................................................................... 61

Chapitre 7 : Classe abstraite et Interface .......................................................................................................................... 63

I. Classe abstraite : .................................................................................................................................................... 63

4

Programmation orientée objet M.CHAKOUJ

1. Le mot clé abstract et méthode abstraite : ........................................................................................................ 63

2. Classe abstraite : ................................................................................................................................................ 63

II. Interfaces : .............................................................................................................................................................. 64

TP5 ..................................................................................................................................................................................... 66

Chapitre 8 : Les collections ................................................................................................................................................ 69

I. La classe ArrayList : ............................................................................................................................................ 69

1. Définition : ......................................................................................................................................................... 69

2. Méthodes : ......................................................................................................................................................... 69

II. La classe générique List<T> .................................................................................................................................... 71

3. Traiter des objets (le tri) : ................................................................................................................................... 74

a. En implémentant l’interface IComparable ......................................................................................................... 74

b. En définissant une classe de comparaison implémentant l’interface IComparer : ........................................... 75

III. Autres classes de collections : ............................................................................................................................ 76

TP 6 .................................................................................................................................................................................... 79

Chapitre 9: Gestion des exceptions ................................................................................................................................... 83

I. Exceptions : ............................................................................................................................................................ 83

II. Gérer une exception ? ............................................................................................................................................ 83

1. Programme sans gestion de l'exception ............................................................................................................ 83

2. Attraper une exception ...................................................................................................................................... 84

3. Programme avec gestion de l'exception : .......................................................................................................... 85

4. Libération des ressources avec finally : .............................................................................................................. 87

III. Lancer une exception ......................................................................................................................................... 87

1. Lancer une exception prédéfinies de C#. ........................................................................................................... 87

2. Déclenchement manuel d'une exception personnalisée : ................................................................................. 88

TP7 ..................................................................................................................................................................................... 90

Chapitre 10 : La Sérialisation binaire ................................................................................................................................. 92

I. Définitions : ............................................................................................................................................................ 92

II. Sérialisation et désérialisation : ............................................................................................................................. 92

Chapitre 11 : Type nullable,type var,type dynamic,Regex,using ....................................................................................... 94

I. Les types nullable : ................................................................................................................................................. 94

1-Intorduction : .............................................................................................................................................................. 94

2.Syntaxe : ...................................................................................................................................................................... 94

II. Le type var : ............................................................................................................................................................ 95

III. Le type dynamic : ............................................................................................................................................... 96

XV. Les expressions régulières : System.Text.RegularExpressions ......................................................................... 96

2. Syntaxe ................................................................................................................................................................... 96

5

Programmation orientée objet M.CHAKOUJ

3. Exemples ................................................................................................................................................................ 97

4. Utilisation en .Net .................................................................................................................................................. 97

a. Validation d'une chaîne .......................................................................................................................................... 97

b. Remplacement dans une chaîne ............................................................................................................................ 98

c. Découpage d’une chaine par séparateur ........................................................................................................... 98

Ressources bibliographiques : .......................................................................................................................................... 100

Annexe :Liste mots clès en C# ...................................................................................................................................... 101

6

Programmation orientée objet M.CHAKOUJ

Chapitre 1 : Introduction à la POO

Objectif du module : L’objectif de ce module vise à ce que le stagiaire utilise les concepts de la programmation orientée objet en développant des applications en mode console avec le langage de programmation C# (prononcé Csharp). Le développement des interfaces graphiques et l’accès aux bases de données sont traités dans les modules "Programmation Evénementielle’’ et ‘’ Programmation Client/Serveur".

I. Programmation orientée objet VS programmation structurée : Dans la programmation il faut faire la distinction entre : • Les langages procéduraux, disposant de la notion de fonction, outil qui permet de structurer un programme en le décomposant en des parties relativement indépendantes.( langage C,pascal…) • Les langages objet, disposant en plus des notions de classe et d’objet ; comme nous le verrons, les classes permettent également de structurer un programme en le décomposant en des parties autonomes.

II. Concepts de base de la Programmation Orientée Objet(POO) :

1-Définitions : La programmation orientée objet est une programmation qui s’inspirer du monde réel et se base sur le

principe d’interaction entre des objets (briques logiciels).

Aujourd’hui l’approche objet occupe une place prépondérante dans le génie logiciel. En effet, ces dernières années nous avons assisté tout d’abord à une utilisation plus large des langages de programmation objet de référence comme C++, C# et Java et ensuite à l’introduction des concepts objet dans d’autres langages comme par exemple VB.NET, Perl et même Cobol.

2-Les avantages de la POO :

Par rapport à une approche fonctionnelle associée à un développement classique mené à l’aide des langages procéduraux, on est en droit de s’interroger sur les avantages qu’apporte réellement le développement à l’aide d’un langage objet comme par exemple C++, C# ou Java. En fait, deux avantages prépondérants sont mis en général en avant lorsque l’on choisit une approche objet : • La modularité – Par construction, étant donné que l’on conçoit des classes représentant une entité de taille limitée en données et en opérations, il est plus aisé de construire des systèmes modulables.

7

Programmation orientée objet M.CHAKOUJ

• La réutilisabilité : La définition d’un système à l’aide de classe ayant chacune la responsabilité d’un sous-ensemble de données et des opérations associées favorise fortement la potentialité de trouver des classes réutilisables. La réutilisation de classe se réalise soit sur le plan métier à l’intérieur d’une même entreprise dans des applications différentes, soit sur le plan technique à l’échelle de tous les développements réalisés à l’aide d’un même langage. Sur ce dernier aspect, c’est toute l’approche du développement par composant qui est en jeu. Au-delà de ces deux avantages majeurs et compte tenu de la plus grande modularité dans la construction d’une application à l’aide d’objets, la maintenance élémentaire de chaque classe est en soi plus simple à réaliser que celle d’un logiciel unique traitant toutes les données d’un système. Il importe bien entendu dans l’approche objet de construire son système en veillant à minimiser le nombre de relations entre classes.

3-La notion d’objet :

Le concept d’objet consiste à regrouper dans une même entité des données qu’on nomme des attributs (ou encore des champs) , ces données peuvent être manipuler à l’aide des fonctions qu’on nomme méthodes (ou, parfois, fonctions membres). Un objet possède donc : Les attributs: Les attributs sont les éléments d'un objet qui représentent les champs (variables) ce sont eux qui stockent les données à gérer. Tout comme n'importe quelle autre variable, un champ peut posséder un type quelconque défini au préalable : nombre, caractère, ..., ou même un type objet. Autrement dit les attributs se sont des données qui représentent l’état d’un objet Les méthodes: Les méthodes sont les traitements définies dans la classe de l’objet. Is servent d'interface entre les données et le programme utilisant l’objet. Sous ce nom obscur se cachent simplement des procédures ou fonctions destinées à traiter les données. Les champs et les méthodes d'un objet sont ses membres.

4-La notion de classe :

Une classe est une description abstraite d’un objet (déclaration d’un type), pouvant donner naissance à différents objets disposant de la même structure de données (mêmes attributs) et des mêmes méthodes. Différents objets d’une même classe se distinguent par les valeurs de leurs attributs ; en revanche, ils partagent les mêmes méthodes. Elle peut être considérée en quelque sorte comme un moule. Un objet est donc issus d’une classe c’est le produit qui sort d’un moule. On dit qu’un objet est une instanciation d’une classe, donc un objet peut être appelé une instance. Exemple : La figure suivante modélise une classe Robot :

8

Programmation orientée objet M.CHAKOUJ

Un objet robot est caractérisé par les attributs : VitG,VitD, sensG, sensD.Pour pouvoir manipuler ces attributs nous devons forcément utiliser les méthodes :reculer(),avancer(),Tourner(), et freiner().

5-La notion d’encapsulation :

Par rapport à l’approche classique, l’approche objet se caractérise par le regroupement dans une même classe de la description de la structure des attributs et de la description des opérations. Ce regroupement des deux descriptions porte le nom d’encapsulation données-traitements. Plus précisément, les données ne sont accessibles qu’à partir d’opérations définies dans la classe comme l’indique la figure ci-dessous :

6-Communication entre objets :

Les objets vont être capables d’interagir et de communiquer entre eux par l’intermédiaire des méthodes publiques en échangeant des messages : Pour envoyer un message au robot : -On appelle la méthode (exemple : tourner() )

-En spécifiant l’objet cible ( exemple : monRobot)

- En précisant d’éventuels paramètres

L’appel de méthode est effectué par un autre objet (exemple un objet de la classe Pilote :

9

Programmation orientée objet M.CHAKOUJ

Note : Dans la POO, les classes sont des abstractions des entité du champ de l’étude de l’application.

7-La notion d’abstraction :

Il est important de comprendre que la programmation n’est pas un processus de reproduction informatique de toutes les détails d’un concept du monde réel .Lorsque nous allons programmer une classe personne, nous n’allons pas essayer de modéliser tous ce qui concerne une personne, mais seulement les informations spécifiques à l’application à développer. Ce concept est appelé abstraction et il est important pour surmonter la complexité du monde réel, donc il faut rester toujours dans le contexte de l’application lors de la conception des classes. Remarque : Pour représenter une classe, on utilise le diagramme de classe du langage de modélisation UML (Unified Modeling Language) :

III. Le Langage C# : Le C# est un langage de programmation orientée objet .Apparu en 2001, il est principalement inspiré par le Java (1995) mais aussi par le C++. Ce langage dont le nom se prononce « C-Sharp » à été créé par Microsoft à été normalisé par l’ECMA l’année de sa sortie (puis par l’ISO deux ans plus tard). Il y a eu quatre versions du C# implémentant toujours quelques fonctionnalités supplémentaires. Le C# étant un produit du framework .NET leurs évolutions sont très liées. Le C# 2.0 est sorti avec le framework 2.0 (VS 2005), le C# version 3 (introduit avec Visual Studio 2008 en novembre 2007) a apporté : les propriétés automatiques ,les initial-isations de collections ,les variables déclarées avec var les types anonymes ,les expressions lambda,Linq .

10

Programmation orientée objet M.CHAKOUJ

Pour utiliser la syntaxe du C#3.0 il faut utiliser le compilateur adapté dans un environnement cible 2.0 ou supérieur. Ce compilateur est notamment disponible et implémenté avec l’IDE VisualStudio 2008. C# version 4, introduit avec Visual Studio 2010, et apporte plusieurs nouveautés (le type dynamic, arguments nommés et par défaut,…)

Cochez les bonnes réponses : Q1) Une classe est :

o un ensemble d’objets possédant le même nom.

o Un ensemble d’instructions

o une déclaration d’un type, possédant des données propres et des traitements. Q2) Dans un objet on trouve une partie comportementale statique et une partie comportementale dynamique. Donnez la signification de chacune de ces parties.

o Partie statique : représente l'état de l'objet grâce à des méthodes Partie dynamique représente le comportement opératoire de l'objet

o Partie statique : représente l'état de l'objet grâce à des attributs Partie dynamique représente le comportement opératoire de l'objet

o Partie statique : représente le comportement opératoire de l'objet Partie dynamique : représente l'état de l'objet grâce à des méthodes

o Partie statique : représente le comportement opératoire de l'objet grâce à des méthodes Partie dynamique : représente l'état de l'objet grâce à des attributs 10) Comment agit-on sur un objet ?

o On agit sur un objet à travers la modification de ses attributs.

o On agit sur un objet en passant ses attributs en paramètre.

o On agit sur un objet en utilisant un système de messagerie e-mail.

o On agit sur un objet à travers l'envoi de messages grâces aux méthodes. Q3) Expliquer le mécanisme de communication entre objets par un exemple Q4) Citez les avantage de la POO par rapport à la programmation structurée. Q5) L’encapsulation est le faite de :

o qualifier les attributs private et les méthodes public ;

o attribuer des qualificateurs de visibilités aux membres ;

o regrouper les attributs (données)et les méthodes(traitements) dans la classe.

o restreindre l’accès aux attributs à certaines opérations définies dans la classe. Q6) C# est un langage de programmation :

o orienté objet développé par Sun ;

o procédural développé par MicrosofT

o orienté objet développé par Microsoft Q7) la dernière version de C# est C# 4 ?

o Vrai

o Faux

TEST chapitre 1 :

11

Programmation orientée objet M.CHAKOUJ

I. L’IDE Visual Studio de Microsoft : Visual Studio est l’interface de développement de Microsoft. Elle est composée d’un ensemble d’outils permettant aux développeurs de créer des applications pour les plateformes .NET. Visual Studio 2010 est distribué en plusieurs éditions :

• Express : Microsoft fournit gratuitement cette édition limitée de Visual Studio 2010 dans un but de formation pour les développeurs. Elle réunit toutes les fonctionnalités de base pour la création de projets.

• Professional : édition à destination des développeurs professionnels seuls ou au sein de petites équipes. Les outils de débogage et de tests unitaires font partie des fonctionnalités notables de cette édition.

• Premium : pour les équipes professionnelles travaillant sur des projets nécessitant plus d’interactions entre leurs membres. En plus des fonctionnalités de l’édition Professional, cette édition offre les fonctionnalités de test de l’UI (Interface utilisateur), de développement de base de données et de la génération au déploiement en passant par les tests.

• Ultimate : en plus des fonctionnalités de l’édition Premium, cette édition contient l’IntelliTrace, outil supplémentaire pour le débogage d’applications, le gestionnaire de tests, et des outils de design d’architecture d’applications. Dans ce polycopie, l’édition Ultimate sera utilisée pour la présentation des exemples bien que la totalité soit valable avec l’édition Express.

II. Création du premier projet : Comme indiqué dans le guide pédagogique nous allons développer tout au long de ce module que des applications console. Pour créer un projet Application console avec Microsoft VS 2010, allez au menu démarrer, tous les programmes, cherchez le logiciel Microsoft VS 2010, lancez le ! Sélectionnez Nouveau Projet dans l’anglet Fichier !

Chapitre 2 : L’IDE Visual Studio 2010 et l’architecture du dotNet

12

Programmation orientée objet M.CHAKOUJ

Puis sélectionnez Visual C# Windows pour le type de projet , et Application console pour le modèle :

Nommez le projet tp , et sélectionnez un dossier de votre choix à l’aide du bouton Parcourir . Enfin cliquez sur OK. Le projet se présente sous la forme d’une arborescence :

Programmation orientée objet

Par défaut le projet tp contient le fichier source Program.cs Dans ce fichier vous aller trouver le squelette de la classe programme

Testons maintenant ce projet. Tout d’abord ajoutons des instructions dans le corps de la méclasse Program. :

13

Par défaut le projet tp contient le fichier source Program.cs (l’extension cs signifier Csharp).

squelette de la classe programme :

projet. Tout d’abord ajoutons des instructions dans le corps de la mé

Si l’explorateur de solution ne s’affiche paspouvez l’afficher à partir de l’onglet Affichage (raccourci clavier :clts+w,s)

M.CHAKOUJ

(l’extension cs signifier Csharp).

projet. Tout d’abord ajoutons des instructions dans le corps de la méthode Main de la

Si l’explorateur de solution ne s’affiche pas, vous pouvez l’afficher à partir de l’onglet Affichage

Programmation orientée objet

Pour lancer l’exécution, il y a plusieurs méthodes pour ce faire : Soit le lancer à partir de l’application

Soit directement avec la touche F5 Soit avec la commande ctr+F5 qui demande à l’utilisateur de taper une touche à la fin de l’exécution de toute instructioRemarques : La différence entre projets et solutions

• Un projet est un ensemble de fichiers qui seront compilés en un seul assemblage• Une solution est un ensemble d’un

d’entrée, une solution a un projet de solutions car son nom est en gras.

Une application C# doit contenir obligatoirement une méthostatique via les mots clés public et static, qui spécifient respectivement auaccessible depuis l’application et en dehors, que la méthode est globale et que la classe n’a pas besinstanciée pour pouvoir l’appeler.

III. L’architecture de .NET FrameworkVous allez, sans doute, remarquer que tout fichier d’une classe en C#, contient en entête un ensemble de lignes qui commencent par le mot clé Le schéma suivant montre l’architecture en couches de .NET Framework et l’emplacement de cette librairie de classes :

Le CLR est l’environnement d’exécution des applications. Il est Language Specification) qui est un ensemble de règles à respecterexécuter avec le CLR. La grande force du CLR est de pouvoir combiner plusieurs assemblages quel que soit le langage dans lequel ils ont été écrits. Une application écrite en C# pourra ainsi faire référence et utiliser une

14

l’exécution, il y a plusieurs méthodes pour ce faire : Soit le lancer à partir de l’application

F5 Soit avec la commande ctr+F5 qui demande à l’utilisateur de taper une

touche à la fin de l’exécution de toute instruction.

La différence entre projets et solutions Un projet est un ensemble de fichiers qui seront compilés en un seul assemblageUne solution est un ensemble d’un ou plusieurs projets. De la même manière qu’un projet à un point d’entrée, une solution a un projet de démarrage. Ce projet est identifiable dans l’explorateur de solutions car son nom est en gras.

Une application C# doit contenir obligatoirement une méthode Main().Cette méthode doit être publique et statique via les mots clés public et static, qui spécifient respectivement au compilateur que la méthode est accessible depuis l’application et en dehors, que la méthode est globale et que la classe n’a pas bes

L’architecture de .NET Framework Vous allez, sans doute, remarquer que tout fichier d’une classe en C#, contient en entête un ensemble de lignes qui commencent par le mot clé using qui fait référence à des bibliothèques de classes.

Le schéma suivant montre l’architecture en couches de .NET Framework et l’emplacement de cette librairie

Le CLR est l’environnement d’exécution des applications. Il est multi-langage grâce au CLS (Common Language Specification) qui est un ensemble de règles à respecter par un langage

avec le CLR. La grande force du CLR est de pouvoir combiner plusieurs assemblages quel que soit été écrits. Une application écrite en C# pourra ainsi faire référence et utiliser une

M.CHAKOUJ

l’exécution, il y a plusieurs méthodes pour ce faire : Soit le lancer à partir de l’application :

F5 Soit avec la commande ctr+F5 qui demande à l’utilisateur de taper une

Un projet est un ensemble de fichiers qui seront compilés en un seul assemblage (.exe ou .dll). ou plusieurs projets. De la même manière qu’un projet à un point

projet est identifiable dans l’explorateur de

de Main().Cette méthode doit être publique et compilateur que la méthode est

accessible depuis l’application et en dehors, que la méthode est globale et que la classe n’a pas besoin d’être

Vous allez, sans doute, remarquer que tout fichier d’une classe en C#, contient en entête un ensemble de iothèques de classes.

Le schéma suivant montre l’architecture en couches de .NET Framework et l’emplacement de cette librairie

grâce au CLS (Common

pour pouvoir le compiler et avec le CLR. La grande force du CLR est de pouvoir combiner plusieurs assemblages quel que soit

été écrits. Une application écrite en C# pourra ainsi faire référence et utiliser une

15

Programmation orientée objet M.CHAKOUJ

librairie écrite en VB. Pour en arriver à ce niveau de compatibilité, le compilateur convertit le code en langage intermédiaire (IL) permettant d’être interprété de la même manière quel que soit le langage dans lequel le code a été écrit. La compatibilité des types entre les différents langages est assurée par le CTS (Common Types System). Chaque type de base d’un langage possède un équivalent dans le Framework .NET et donc en langage intermédiaire. Ainsi, un integer en VB et un int en C# seront du même type System.Int32. Une fois compilée, une application se résume à au moins un fichier exécutable. Celui-ci est en langage intermédiaire. Lorsque l’exécution est lancée, le CLR examine le manifeste pour déterminer si les conditions de sécurité sont respectées. Si tel est le cas, le CLR crée un processus pour héberger l’application et le code est compilé du langage intermédiaire en code binaire par le compilateur JIT (Just In Time). Ce code généré est ensuite stocké en mémoire de manière à ne pas être recompilé en cours d’exécution et à optimiser les performances. La troisième couche : librairie de classes fondamentales Le Framework .NET est composé de plusieurs bibliothèques de classes, classées en espaces de noms, organisés de manière hiérarchique à partir de l’espace de noms racine System. Les fonctionnalités (classes) en relation sont donc classées au sein d’un même espace de noms. System.IO, par exemple, regroupe les types ayant pour but d’interagir avec le système de fichiers. Remarques : -Ces bibliothèques de classes sont consultables via l’explorateur d’objets

La classe Console qui se trouve dans l’espace de noms System se déclare comme :System.Console. Les NameSpaces servent à ranger les classes un peu comme dans des dossiers. Ces imports d’espaces de nom permettent d’accéder directement à tous les éléments contenus (appart les NameSpaces qu’il contient) sans avoir à mentionné où il est rangé. Plus vous ferrez de using plus vous aurez de propositions à l’auto complétion dans VS 2008, d’où l’intérêt de limiter l’usage des using car cela permet une auto complétion plus rapide et plus pertinente

16

Programmation orientée objet M.CHAKOUJ

Q1-C’est quoi Visaul Studio ? Q2-VS 2010 est un IDE open source :

o Vrai

o Faux Q3-Avec VS2010 on peut développer que des applications consoles :

o Vrai

o Faux Q4-Un projet C# peut avoir plusieurs objets de démarrage :

o Vrai

o Faux Q5-La fonction static void Main() est le point d’entrée où commence l’exécution d’un programme C# :

o Vrai

o Faux Q6-C’est quoi le dotNet framework ?

Q7-Un espace de nom est :

a)la définition d’une classe

b)conteneur du code d’un ensemble de classe.

c) un « répertoire logique » contenant des classes. Comme pour les fichiers, les classes doivent avoir un nom unique dans un espace de noms donné.

TEST chapitre 2 :

17

Programmation orientée objet M.CHAKOUJ

I. Commentaires en C# :

Les commentaires peuvent également servir pour fournir une documentation au format XML. Cette documentation XML pourra être interprétée par l’IntelliSense pour fournir la description des membres, des paramètres ou encore des exceptions.

II. Les types de base : C# vous donne la possibilité de travailler avec deux types de données (objets), le type valeur et le type référence. Les types valeur contiennent les données tandis que celles de référence contiennent une référence vers la donnée stockée quelque part dans la mémoire. Les types primitives telles que int,char float,structures,…, sont des type valeur. Les types object,string,les tableaux sont des types référence. Le tableau ci-dessous liste les type de base en C# :

Remarques: -Si vous voulez trouver facilement la valeur maximale et la valeur minimale d’un type numérique, faites « System.Int32.MaxValue » pour retourner le plus grand des int ou MinValue pour trouver le plus petit. -C# respecte la casse :nbr et Nbr sont deux identificateurs différents. -Noter qu’en C# tout est objet, même les types sont des classes. Pour découvrir les différents membres d’une classe (par exmeple la classe char) utiliser l’explorateur d’objet du VS :

Chapitre 3 C# : Notions de base

18

Programmation orientée objet M.CHAKOUJ

L’instruction suivante déclare une variable de type entier (int) et lui affecte une valeur. Le compilateur lève une exception si un type valeur est utilisé sans avoir été affecté : int i = 1;

19

Programmation orientée objet M.CHAKOUJ

-L’opérateur is permet de déterminer le type d’un objet : -Les constantes :

III. Identificateurs en C# Un identificateur est le nom de variable mais aussi de fonction, de classe, etc. Différence par rapport au C: C# accepte les lettres accentuées.

IV. Opérations d’entrée/sortie

1. Affichages

20

Programmation orientée objet M.CHAKOUJ

Remarques : -Pour forcer un fond bleu, on écrit : Console.BackgroundColor = ConsoleColor.Blue; Console.ForegroundColor = ConsoleColor.Red; Console.Clear();//effacer le contenu de l’écran -Pour changer le titre de la fenêtre : Console.Title = "Mon application"; - Pour changer la taille de la fenêtre (et la faire passer à 38 lignes de 64 caractères) : Console.SetWindowSize(64, 30); -Pour positionner le curseur au point (10, 20) et afficher du texte en rouge sur fond noir : Console.SetCursorPosition(10, 20); -Du sons :

2. Lecture de données saisies au clavier

V. L’instruction if : Analysons quelques instructions qui sont valide en langage C (qui considère un int non nul comme une valeur booléenne true ) mais qui ne le sont pas en C# (on suppose que i est de tout type différent de bool) :

21

Programmation orientée objet M.CHAKOUJ

VI. L’instruction Switch : En C# Switch accepte les chaînes de caractères (objets string) dans le sélecteur. Comme en C, l’instruction switch effectue un aiguillage vers une ou plusieurs instructions en fonction du contenu d’une variable de contrôle : switch (val) { case valeur : une ou plusieurs instructions; break; case valeur : une ou plusieurs instructions; break; default : une ou plusieurs instructions; break ; }

VII. Les boucles : Les instructions for, while et do while sont semblables. Comme en C, trois formes de boucle (while, do while et for) sont possibles. Quelle que soit la forme de la boucle, les accolades peuvent être omises si le corps de la boucle se résume à une seule instruction. Un if, même compliqué, ainsi qu’un do, un while, un for ou encore un switch sont assimilés à une seule instruction.

22

Programmation orientée objet M.CHAKOUJ

23

Programmation orientée objet M.CHAKOUJ

Exercice 1 : Ecrire un programme en C# qui permet de calculer la somme ,le produit de deux nombres saisis par l’utilisateur. Exercice 2: Ecrire un programme réalisant une calculette pour les opération + ,-,/,*.

Au début une menu doit être afficher à l’utilisateur ,puis on lui demande de choisir l’opération choisie, puis la saisi des deux opérandes.

Exercice 3: Ecrire un programme qui permet d’afficher le maximum parmi 10 nombres saisi au clavier.

Exercice 4: Ecrire un programme en C qui détermine la nème valeur Un de la suite suivante :

U1 = 1

U2 = 1

Un = Un-1 + Un-2.

Exercice 5: Ecrire un programme C# servant à calculer la valeur absolue d'un nombre réel x à partir de la définition de la valeur absolue. La valeur absolue du nombre réel x est le nombre réel |x| : |x| = x , si x ≥ 0 |x| = -x si x < 0

Exercice 6: On souhaite écrire un programme C# de résolution dans R de l'équation du second degré : Ax2 + Bx +C = 0 Exercice 7: Ecrire un programme qui permet de lire le nom,le prénom,la date de naissance d’une personne (contrôler la validité des données).

TP1

Programmation orientée objet

La classe est l’élément central de tout programme C# (et de manière générale de tout programme .NET). Tout doit en effet être regroupé dans une classe. Tout programme exécutable (exe) est constitué d’une ou plusieurs classes dont l’une comprend la foncd’une application console ou Windows). Toute librairie (dll pour Dynamic Link Libraries) est également composée d’une ou plusieurs classes.

I. L’ajout d’une nouvelle classe à un Comment ajouter une classe à notre projet: Bouton droite sur le projet

Nommer la classe Personne. Saisis le code de cette classe : class Personne { // attributs private string prenom; private string nom; private int age; // méthode initialise qui initialise les attributs par les valeurs de ses paramètrespublic void Initialise(string n, string p, int age)

Chapitre 4

24

La classe est l’élément central de tout programme C# (et de manière générale de tout programme .NET).

Tout doit en effet être regroupé dans une classe. Tout programme exécutable (exe) est constitué d’une ou plusieurs classes dont l’une comprend la fonction statique Main, point d’entrée du programme (qu’il s’agisse d’une application console ou Windows). Toute librairie (dll pour Dynamic Link Libraries) est également

nouvelle classe à un projet:

Comment ajouter une classe à notre projet: Bouton droite sur le projet :

initialise qui initialise les attributs par les valeurs de ses paramètres public void Initialise(string n, string p, int age)

Chapitre 4 : Notre première classe en C#

M.CHAKOUJ

La classe est l’élément central de tout programme C# (et de manière générale de tout programme .NET). Tout doit en effet être regroupé dans une classe. Tout programme exécutable (exe) est constitué d’une ou

tion statique Main, point d’entrée du programme (qu’il s’agisse d’une application console ou Windows). Toute librairie (dll pour Dynamic Link Libraries) est également

25

Programmation orientée objet M.CHAKOUJ

{ nom = n; prenom = p; this.age = age; } /* une deuxième définition de la méthode initialise qui initialise les attributs par les valeurs de ceux de l’objet personne passé en paramètre*/ public void Initialise(Personne p) { nom = p.nom; prenom = p.prenom; age = p.age; } // méthode identifie() qui affiche l’état d’un objet public void Identifie() { Console.WriteLine("[{0}, {1}, {2}]", prenom, nom, age); } //méthode presentation() qui retourne une chaine contenant l’état d’un objet public string presentation() { string str; str = string.Format("nom:{0} prenom:{1} age:{2}", nom, prenom, age); return str; } }

II. La portée des attributs et méthodes : Les niveaux d’accès permettent de définir comment vont pouvoir s’effectuer l’instanciation des types et l’appel des méthodes. Le niveau d’accès est défini à l’aide de mots clés précédant la déclaration de la classe, ou du membre. Le tableau suivant présente les modificateurs d’accès disponibles en C#:

Remarque : 1-Les attributs d'une classe sont déclarées private alors que ses méthodes et propriétés sont déclarées public. Cela signifie que l'utilisateur d'un objet (le programmeur) n'a pas accès directement aux données privées de l'objet à l’extérieur de sa classe , mais peux faire appel aux méthodes publiques de l'objet ( notamment à celles qui donneront accès à ses données privées). 2-Si aucun modificateur d’accès n’est précisé sur un membre, il est considéré comme private. 3-Une classe ou une structure sans modificateur d’accès sera considérée comme internal.

26

Programmation orientée objet M.CHAKOUJ

4-Les membres ne pourront jamais étendre leur niveau d’accès au delà de celui du type contenant.

III. Le mot clé this : ‘’ this ‘’correspond à l’instance en cours de traitement. Regardons le code de la méthode Initialise : public void Initialise(string n, string p, int age) { nom = n; prenom = p; this.age = age; } L'instruction : this.age=age signifie que l'attribut age de l'objet courant (this) reçoit la valeur age de la méthode Initialise . Le mot clé this désigne l'objet courant : celui sur lequel s’exécute la méthode Initialise. age désigne un attribut de l'objet courant ainsi que le paramètre age reçu par la méthode. Il faut alors lever l'ambiguïté en désignant l'attribut age par this.age.

IV. Le test de la classe personne : Pour tester la classe Personne nous allons créer un objet p1 de type Personne à partir de la méthode Main() de la classe Program ,:

Voila le résultat d’exécution :

Regardons comment se fait l'initialisation de l'objet référencé par p1 dans le programme appelant : p1.Initialise("Sadouk","Mohamed Amin",22); C'est la méthode Initialise() de l'objet p1 qui est appelée. Donc l'objet this dans la méthode Initialise(), référence ici l'objet p1. Remarque : Pour comprendre la notion des modificateurs d’accès (visibilité des membres d’une classe), essayer d’afficher directement le nom de la personne p1.Lorsque vous taper p1 suivi d’un point , l’outil d’auto-complétion vous donner les choix suivants :

27

Programmation orientée objet M.CHAKOUJ

Vous remarquez que les attributs n’apparaissent pas, mais les méthodes oui, la raison c’est que les attributs sont déclarés private . Comment faire pour pouvoir accéder aux attributs d’un objet à l’extérieur de la classe ? C’est le rôle des Méthodes de lecture et d'écriture des attributs privés.

V. L'opérateur new : L’operateur new permet de créer un objet .Pour créer un objet P1, il faut écrire : Personne p1=new Personne(); Ou bien Personne p1 ; p1=new Personne(); Cela a pour effet de créer un objet de type Personne non encore initialisé : les attributs nom et prénom qui sont des références d'objets de type String auront la valeur null, et âge la valeur 0. Il y a donc une initialisation par défaut.

VI. Constructeurs de classe Un constructeur est une méthode qui porte le nom de la classe et qui est appelée automatiquement lors de la création de l'objet. On s'en sert généralement pour l'initialiser. C'est une méthode qui peut accepter des arguments mais qui ne retourne aucun résultat . Son prototype ou sa définition n’est précédé d'aucun type (pas même void). Si une classe Y a un constructeur acceptant n arguments argi, la déclaration et l'initialisation d'un objet de cette classe pourra se faire sous la forme : NomDeLaClasse NomObjet=new NomConstructeur(Paramètres du constructeur) ; Càd : Y objet = new Y(arg1,arg2, ... argn); Ou Y objet; Objet = new Y(arg1,arg2, ... argn); Constructeur par défaut :

Si le programmeur ne définit pas de constructeur dans sa classe, c’est le constructeur par défaut qui est appelé il est généré automatiquement par le compilateur C# .

Programmation orientée objet

VII. La surcharge d’une méthode Vous avez remarqué, sans doute, que nous surchargé la méthode constructeur (mais attention les signatures doivent être différentes).Pour pouvoir avoir le choix entre plusieurs possibilité d’arguments en entrée il existe la surchméthodes. La surcharge d’une méthode permet surcharge permet de changer les paramètres et le type de retour.Exemple : la classe DateTime contient 12 constructeurs

Testons maintenant ces constructeurs

28

La surcharge d’une méthode : Vous avez remarqué, sans doute, que nous avons données au constructeur plusieurs définitions, on dit qu’on a surchargé la méthode constructeur (mais attention les signatures doivent être différentes).Pour pouvoir avoir le choix entre plusieurs possibilité d’arguments en entrée il existe la surchméthodes. La surcharge d’une méthode permet de changer la signature en gardant le même nom. Une surcharge permet de changer les paramètres et le type de retour. Exemple : la classe DateTime contient 12 constructeurs

:

M.CHAKOUJ

avons données au constructeur plusieurs définitions, on dit qu’on a surchargé la méthode constructeur (mais attention les signatures doivent être différentes). Pour pouvoir avoir le choix entre plusieurs possibilité d’arguments en entrée il existe la surcharge des

en gardant le même nom. Une

29

Programmation orientée objet M.CHAKOUJ

VIII. Le type objet est un type référence :

Lorsqu'on déclare la variable p1 par : Personne p1=new Personne("Mohammed","Ali",33); Pour rentrer un peu dans la technique, au moment de l’instanciation d’un objet, l’opérateur new crée l’objet et le met à une place disponible en mémoire. Cette adresse mémoire est conservée dans la variable p1(dans la pile). On dit que p1 contient une référence vers l’objet. p1 référence l'objet Personne("Mohammed","Ali",30); mais n'est pas l'objet lui-même. En C, on dirait que c'est un pointeur, c.à.d. l'adresse de l'objet créé.

Y : est un objet de type valeur(ex :type de base,structures..)

X : est un objet de type référence (ex :instance d’une classe X)

30

Programmation orientée objet M.CHAKOUJ

Si on écrit ensuite : p1=null;

Ce n'est pas l'objet Personne("Mouhamed","Ali",30) qui est modifié, c'est la référence p1 qui change de valeur. L'objet Personne("Mouhamed","Ali",30) sera "perdu" s'il n'est référencé par aucune autre variable, c’est le ramassage miettes (Garbage Collector )qui s’en occupe de cette tâche, il supprime tous les objets non référencés. Lorsqu'on écrit : Personne p2=p1; on initialise le pointeur p2 : il "pointe" sur le même objet (il désigne le même objet) que le pointeur p1. Ainsi si on modifie l'objet "pointé" (ou référencé) par p1, on modifie aussi celui référencé par p2.

Lorsqu'on écrit : Personne p3=new Personne (p1); il y a création d'un nouvel objet Personne. Ce nouvel objet sera référencé par p3. Si on modifie l'objet "pointé" (ou référencé) par p1, on ne modifie en rien celui référencé par p3.

IX. Passage de paramètres: 1. Passage de paramètres par référence

Dans un passage par référence, le paramètre effectif et le paramètre formel sont une seule et même entité. Si la fonction modifie le paramètre formel, le paramètre effectif est lui aussi modifié. En C#, ils doivent être tous deux précédés du mot clé ref comme l’indique l’exemple ci-dessous.

Résultat : ce code affiche 60.

31

Programmation orientée objet M.CHAKOUJ

Remarque: Lorsqu’un tableau est passé par valeur, c’est la valeur de la référence qui est passée en argument.Comme cette valeur indique où se trouvent les données du tableau, la fonction peut modifier ces données. Mais la fonction est alors bien incapable de modifier la taille du tableau (ou de l’annuler, en plaçant la valeur null dans la référence) car cela nécessite de recréer un tableau et donc de changer la référence.Pour pouvoir le faire il faut passer la référence par référence (ref tableau).Cette constatation est vrai pour tous les type références.

2. Passage de paramètres en sortie : le mot clé out Le passage de paramètres en sortie permet de faire en sorte qu’une méthode force l’initialisation d’une variable (jamais une valeur) passée en argument (toujours par référence) et que l’appelant récupère la valeur initialisée.

La méthode TryParse permet de tester la conversion d’une chaîne. Elle renvoie vrai ou faux en fonction du résultat de la conversion et met à jour l’entier qui est passé en paramètre en utilisant le mot-clé « out ». Si la conversion réussit, alors l’entier nombre est initialisé avec la valeur de la conversion, calculée dans la méthode TryParse(le chiffre1234). Exercices d’application : 1-Ecrire une méthode Permuter() qui permet de permuter le contenu de deux variable de type double passés en paramètre. 2- Ecrire une méthode bool Division(doubl a,doubl b,out s) qui permet de calculer le quotient a/b et mit le résultat dans s.

X. Tableaux statiques

1. La classe Array :

La classe Array s’applique aux tableaux, quel que soit le type des cellules. Des fonctions de cette classe permettent notamment de trier des tableaux ou d’effectuer des recherches dichotomiques dans un tableau trié.

32

Programmation orientée objet M.CHAKOUJ

33

Programmation orientée objet M.CHAKOUJ

2. Syntaxe de déclaration et création d’un tableau:

a. Tableaux à une dimension char [ ] TableCar ;//Déclaration de la référence TableCar = new char[8]; //définition de la taille et allocation de la mémoire création d'un //nouvel objet tableau à 8 cellules Int [] ti = new int[]{100, 200, 300, 400};//avec initialisation

b. Tableau à deux dimensions :

int[,] t = new int[2, 3]; Affectation des valeurs :

TableCar[0] = 'a'; TableCar[1] = '#'; ... TableCar[7] = '?';

34

Programmation orientée objet M.CHAKOUJ

3. Le parcours d’un tableau en lecture avec la boucle foreach :

C’est la boucle qui permet de faire le parcours d’un tableau ou collection d’objets . Syntaxe : foreach(Type identificateurVariableDeParcours in nomTableau) { Instructions en lecture à effectuer sur l’objet pointu } Remarque : Attention, la boucle foreach est une boucle en lecture seule. Cela veut dire qu'il n'est pas possible de modifier l'élément de l'itération en cours. Donc Si nous souhaitons utiliser une boucle pour changer la valeur de notre liste ou de notre tableau, il faudra passer par une boucle for. Exemple : Pour afficher le tableau précédent TableCar : foreach ( char val in TableCar) System.Console.WriteLine ( val ); Exemple : Tris et recherches dichotomiques Pour illustrer les tris et recherches dichotomiques, nous allons créer un tableau d’entiers, le trier et effectuer une recherche dichotomique. On écrit pour cela (n contiendra ici une valeur négative puisque la valeur 5 ne se trouve pas dans le tableau) : int[] ti = {10, 1, 1000, 100}; Array.Sort(ti); // tri de ti int n = Array.BinarySearch(ti, 5); // recherche de la valeur 5 dans ti Exemple du code : static void Main(string[] args) { //déclaration de deux vecteurs de types float float [] t=new float[10]; float[] v = new float[20]; int n; float vr; //controle du nombre de cases à remplir do { Console.Write("donnez le nombre des éléments: "); int.TryParse(Console.ReadLine(), out n); } while (n > 10); //pour remplir tous les cases du tableau on mis t.length au lieu de n for (int i = 0; i < n; i++) { Console.Write("donnez l'élément d'indice " + i+" "); float.TryParse(Console.ReadLine(), out t[i]); } //trier le tableau t en ordre croissant Array.Sort(t); //affichage du tableau Console.WriteLine("\n le tableau t Trier est "); for (int i = 0; i < t.Length; i++)

35

Programmation orientée objet M.CHAKOUJ

{ Console.Write(t[i] + " "); } Console.WriteLine("\nle max du tableau t est "+t.Max()); //copier les éléments de t dans v Array.Copy(t,v,t.Length); Console.WriteLine("\n le tableau v est : "); for (int i = 0; i < v.Length; i++) { Console.Write(v[i] + " "); } //inverser l'ordre des éléments de t Array.Reverse(t); Console.WriteLine("\n le tableau t après inversement est "); for (int i = 0; i < t.Length; i++) { Console.Write(t[i] + " "); } //recherche séquencille Console.WriteLine("\ndonnez lz valeur à rechercher dans t"); float.TryParse(Console.ReadLine(), out vr); Console.WriteLine("\nla valeur " + vr + " se trouve dans la case d'indice " + Array.IndexOf(t, vr)); //recherche dichotomique Array.Sort(t);//le tableau doit etre trier pour pouvoir utiliser la recherche binaire Console.WriteLine("\ndonnez lz valeur à rechercher dans t"); float.TryParse(Console.ReadLine(), out vr); Console.WriteLine("\nla valeur "+vr+" se trouve dans la case d'indice "+Array.BinarySearch(t,vr)); Exercice d’application : Ecrire le programme qui permet de saisir les noms de N stagiaires: -Affiche l’indice de la première occurrence du nom Salmi ; -Trier le tableau Remarque : Il est possible, avec les tableaux d’object, de créer des tableaux dont chaque cellule a un type particulier. Object[] o = new object[4];

o[0] = "Chaine !";//une chaine

o[1] = 12;//un entier

o[2] = 12.456;//un double

o[3] = 'D';//un caractère

foreach (Object élément in o)

{

Console.WriteLine(élément);

}

Exercice :

Ecrire la boucle qui permet d’incrémenter les entiers, et de concaténer ‘’*-*’’ avec les chaines contenues dans le tableau précédent ;

36

Programmation orientée objet M.CHAKOUJ

XI. Les chaines de caractères : la classe System.String Les chaînes de caractères sont représentées par des instances de la classe System.String du .NET Framework. Les instances de cette classe sont immuables, c’est-à-dire que la création d’une nouvelle chaîne (suite à une concaténation par exemple), nécessite la création d’une nouvelle instance de la classe String. La classe String contient en interne un tableau de char, c’est-à-dire un tableau de caractères ; les caractères d’une chaîne sont donc indicés en partant de 0.En C#, le mot-clé string est un raccourci pour la classe System.String. Longueur d’une chaine : string chaîne = “Bonjour !”; int longueur = chaîne.Length; // Retourne 9 Accès en lecture à un caractère : L’opérateur [] permet d’extraire un caractère de la chaîne mais n’agit qu’en lecture : string s="Bonjour"; char c = s[0]; // Correct. c contient ‘B’ s[0] = ‘X’; // !!!! erreur de syntaxe !!! Concaténer deux chaines : string s; s = String.Concat(“Bonjour”, “ tout le”); s = s + “ monde !”; Console.WriteLine(s); // Affiche “Bonjour tout le monde !” Extraire une sous chaine : L’exemple suivant montre comment extraire le mot « tout » dans la chaîne de caractères « Bonjour tout le monde ! ». string s; s = “Bonjour tout le monde !”; s = s.Substring(8, 4); // La variable s contient “tout” Comparaison de deux chaines : Les opérateurs == et != (mais non <, <=, etc.) permettent de comparer deux chaînes (== et != comparent les contenus de chaînes, ce qui n’est pas vrai pour les tableaux et les objets où ce sont uniquement les références qui sont comparées) : string s1="Bonjour", s2="Hello"; if (s1 == s2) ..... // les deux chaînes ont-elles les mêmes contenus ? if (s1 == "Bonjour") ..... // la chaîne a-t-elle Bonjour comme contenu ? Les opérateurs == et != appellent en fait la méthode Equals de la classe String. Méthodes principales de la classe String :

37

Programmation orientée objet M.CHAKOUJ

38

Programmation orientée objet M.CHAKOUJ

XII. Les structures : Les classes encapsulant les types élémentaires dans .NET Framework sont des classes de type valeur du genre structures. Dans le CLS une classe de type valeur est telle que les allocations d'objets de cette classe se font directement dans la pile et non dans le tas, il n'y a donc pas de référence pour un objet de type valeur et lorsqu'un objet de type valeur est passé comme paramètre il est passé par valeur. Constructeur : Les classes-structures de type valeur peuvent comme les autres classes posséder un constructeur explicite (pas de constructeur sans paramètre), qui comme pour tout classe C# doit porter le même nom que celui de la classe-structure. Déclaration de classe-structure : struct StructPerso { public int a; private string chaine; public void meth( int x){ .... corps de la méthode } public StructPerso (int a,string chaine ){ .... corps du constructeur } } Instanciation : StructPerso y = new StructPerso (2,”dadi” ) ; Exemple :

using System; struct Eleve { public string refEleve;

public Eleve(string nom, string prenom) {

refEleve=nom+", "+prenom; } }

class Exercice

39

Programmation orientée objet M.CHAKOUJ

{ public static void Main( ) {

Eleve etudiant = new Eleve("Dumas","Alexandre"); Console.WriteLine("identité : "+etudiant.refEleve); Console.ReadLine();

} }

Structures et classes : Structures et classes ont beaucoup de choses en commun (notamment des méthodes qui peuvent être implémentées comme membres de la structure). Structures et classes présentent néanmoins des différences notables. • Les variables structurées sont de type « valeur » (comme int, float, etc., mais pas les string) tandis que les véritables objets (variables d’une classe) sont de type « référence ». • Les structures ne peuvent hériter d’aucune classe ou structure et ne peuvent servir de base pour aucune classe ou structure dérivées. • Les champs d’une structure ne peuvent pas être explicitement initialisés dans la définition même du champ (contrairement aux champs d’une classe). • Une structure peut contenir zéro, un ou plusieurs constructeurs mais pas de constructeur par défaut (autrement dit, pas de constructeur sans argument). • Une variable structurée peut être créée comme nous l’avons fait précédemment mais également par new.

XIII. Les énumérations Un type particulier que nous allons également utiliser est l’énumération. Cela correspond comme son nom l’indique à une énumération de valeurs(ici l’énumération EtatCivil qui comprend quatre valeurs) : //déclaration du type enum EtatCivil { Célibataire, Marié, Divorcé, Veuf } ..... EtatCivil ec; // déclaration d’un variable ec de type EtatCivil Console.WriteLine("donnez l'état civil de la personne"); Enum.TryParse (Console.ReadLine(),true, out ec); //true pour ne pas respecté la casse //(Majuscule et minuscule) switch (ec) { case EtatCivil.Célibataire :

Console.WriteLine("Célibataire"); break; case EtatCivil.Marié :

Console.WriteLine("Marié"); break; case EtatCivil.Divorcé :

Console.WriteLine("Divorcé"); break; case EtatCivil.Veuf :

Console.WriteLine("Veuf"); break; } Ou bien if(ec== EtatCivil.Célibataire) Console.WriteLine("Célibataire");

40

Programmation orientée objet M.CHAKOUJ

else if….. La première ligne (définition enum) doit être placée dans la classe mais en dehors d’une fonction(ou dans un autre fichier ) . La définition enum peut être terminée par un point-virgule mais cela n’est pas obligatoire. Une énumération est un type dont toutes les valeurs définies sont des entiers. La première vaut 0, et chaque valeur suivante prend la valeur précédente augmentée de 1. C’est-à-dire que Célibataire vaut 0, Marié vaut 1, etc.

XIV. Les fichiers texte en C# :

1. Créer un fichier Création sur le disque dur d'un fichier vide au format Unicode en utilisant un flux de type StreamWriter. using System ; using System.IO ; class CreerUnFichierTexte { static void Main ( string [ ] args ) { StreamWriter fluxWrite = new StreamWriter ("c:\\essai.txt"); Console.WriteLine ("Fichier essai.text créé sur le disque dur."); Console.WriteLine ("Il écrase les données déjà présentes"); Console.ReadLine (); } 2. Téster la présence d’un fichier Si le fichier essai.txt n'est pas déjà présent sur le disque dur, on le crée en utilisant un flux de type StreamWriter, s'il est déjà présent on envoi un message console et l'on n'écrase pas le fichier déjà présent. Il faut utiliser la classe System.IO.File qui ne contient que des méthodes static pour la manipulation, la lecture et l'écriture de fichiers sur disque et en particulier la méthode "public static bool Exists ( string path )" qui permet de savoir si un fichier existe physiquement à partir d'un chemin complet passé en paramètre : using System ; using System.IO ; class CreerUnFichierTexte { static void Main(string[ ] args) { if ( !File.Exists("c:\\essai.txt") ) { StreamWriter fluxWrite = new StreamWriter("c:\\essai.txt"); Console.WriteLine("Fichier essai.text créé sur le disque dur."); Console.WriteLine("Il n'écrase pas les données déjà présentes"); } else Console.WriteLine("Fichier essai.text déjà présent sur le disque dur."); Console.ReadLine(); /* Afin de tester le programme effacez physiquement le fichier c:\essai.txt */ }} 3. Lire et ecrire dans un fichier texte Si le fichier essai.txt n'est pas déjà présent sur le disque dur, on le crée et on écrit des données dedans, s'il est déjà présent on le lit et on affiche son contenu. using System ;

41

Programmation orientée objet M.CHAKOUJ

using System.IO ; class CreerUnFichierTexte { static void Main(string[ ] args) { if ( !File.Exists("c:\\essai.txt") ) { StreamWriter fluxWrite = new StreamWriter("c:\\essai.txt"); Console.WriteLine("Fichier essai.text créé sur le disque dur."); Console.WriteLine("Il n'écrase pas les données déjà présentes"); for(int i=1; i<10; i++) fluxWrite.WriteLine("texte stocké par programme ligne N : "+i); fluxWrite.Close(); } else { Console.WriteLine("Contenu du fichier essai.text déjà présent :"); StreamReader fluxRead = new StreamReader("c:\\essai.txt"); string ligne; while((ligne = fluxRead.ReadLine()) != null) Console.WriteLine(ligne); fluxRead.Close(); } Console.ReadLine(); } /* Afin de tester le programme effacez physiquement le fichier c:\essai.txt */ } 4.Recopier tout vers un fichier test Si le fichier essai.txt n'est pas déjà présent sur le disque dur, on le crée et on écrit des données dedans, s'il est déjà présent on le lit et on affiche son contenu. Dans cette version identique au précédent on utilise l'instruction de bloc using. using System ; using System.IO ; class CreerUnFichierTexte { static void Main(string[ ] args) { if ( !File.Exists("c:\\essai.txt") ) { using (StreamWriter fluxWrite = new StreamWriter("c:\\essai.txt")) { Console.WriteLine("Fichier essai.text créé sur le disque dur."); Console.WriteLine("Il n'écrase pas les données déjà présentes"); for(int i=1; i<10; i++) fluxWrite.WriteLine("texte stocké par programme ligne N : "+i); } } else { Console.WriteLine("Contenu du fichier 'essai.text' déjà présent :"); using (StreamReader fluxRead = new StreamReader("c:\\essai.txt")) {

42

Programmation orientée objet M.CHAKOUJ

string ligne; while((ligne = fluxRead.ReadLine()) != null) Console.WriteLine(ligne); Console.WriteLine("\nRecopie en cours ..."); } using (StreamReader fluxRead = new StreamReader("c:\\essai.txt")) { StreamWriter fluxWrite = new StreamWriter("c:\\copyEssai.txt"); string ligne; while((ligne = fluxRead.ReadLine()) != null) fluxWrite.WriteLine("copie < "+ligne+" >"); fluxWrite.Close (); } using (StreamReader fluxRead = new StreamReader("c:\\copyEssai.txt")) { Console.WriteLine("\nContenu de la copie 'copyEssai.txt' :"); string ligne; while( (ligne = fluxRead.ReadLine( ) ) != null) Console.WriteLine(ligne); } } Console.ReadLine(); } /* Afin de tester le programme effacez physiquement le fichier c:\essai.txt */ }

43

Programmation orientée objet M.CHAKOUJ

Exercice 1 : Soit la classe Stagiaire qui modélise un stagiaire et qui comporte les attributs suivants : codeStagiaire int non String prenom String niveau int 1) Codage de la class Stagiaire :

a. Ecrire la class Stagiaire b. Ajouter un constructeur sans argument. c. Ajouter un constructeur qui initialise tous les attributs de la classe Stagiaire. d. Ajouter une méthode affichage() qui affiche la description du stagiaire.

2) Codage de la classe Program : -Créer le stagiaire Slimani Abbas ,ayant le code 123,1ére année. -Créer un tableau contenant 5 instance de la classe stagiaire(leurs informations seront saisies au clavier) en plus du stagiaire Slimani. -Afficher les données de ces stagiaires. Exercice 2 : On souhaite gérer la répartition des modules entre les formateurs d’un institut de formation professionnelle. Soit la classe module qui modélise un module et qui comportera les attributs suivants : référence intitule formateur (matricule du Formateur qui enseigne ce module) Soit la classe Formateur qui modélise un Formateur et qui comportera les attributs suivants : matricule nom prenom sexe (‘M’,’F’) age spacialité echelle Salaire_brut NbreHeuresSup Taux_horaire Taux_IGR Travail à faire : 1- Codage de la classe Module

a- Ecrire la classe Module . b- Ajouter un constructeur sans argument qui initialise l’attribut référence de la class Module ; la

référence doit avoir la valeur du compteur. c- Ajouter un constructeur qui initialise tous les attributs de la classe Module.

d- Ajouter à cette classe une méthode description() qui retourne les valeurs des attributs

séparées par un espace. e- Ajouter à cette classe une méthode afficherInfo() qui affiche la référence et l’intitulé.

2- Codage de la classe Formateur a. Ecrire la classe Formateur avec un compteur des objets créés. b. Ajouter à cette classe une méthode Description() qui retourne les valeurs des attributs

séparées par un espace. c. Ajouter une méthode permettant de calculer le salaire Net à payer pour un Formateur

donné, sachant que :

TP2

44

Programmation orientée objet M.CHAKOUJ

SalaireNet = [SalaireBrut + (NbreheuresSup * Taux_horaire)] * (1 -

Taux_IGR)

3. Codage de la classe de test Program : a. Déclarer un vecteur de type Module b. Déclarer un vecteur de type Formateur. c. Créer 4 instances de la classe Module.

-pour la première instance les valeurs des attributs seront initialisés par vous ; -pour la deuxième instance les valeurs des attributs seront données par l’utilisateur.

d. Créer 2 instances de la classe Formateur e. Ecrire une méthode qui affiche le formateur qui enseigne un module dont la référence est passé en

paramètre f. Ecrire une méthode qui affiche tous les modules enseignés par un formateur dont le matricule est

passé en paramètre.

. Exercice 3 :

1. Créer une Classe ou une Structure Point ayant les champs x, y et éventuellement des constructeurs . Ajouter une méthode permettant de calculer la distance à l’origine √(x2+y2) . 2. Ajouter une autre méthode permettant d’afficher les coordonnés d’un point donné et la distance à l’origine . 3. Ecrire un programme de test pour créer deux points A(12,10) et B(4, 3), et afficher leurs coordonnés et la distance à l’origine. 4. Affecter les coordonnés de B à A et afficher les nouvelles informations du point A.

Exercice 4 : La société AlphGet souhaite développer une solution pour la gestion des voyages d’une agence de transport. Le responsable désire avoir la possibilité de mettre à jour quotidiennement les voyages de l’agence. Les classes utilisées dans cette application sont : Véhicule Chauffeur Voyage

codeVehicule Immatriculation DateCirculation

codeChauffeur nomChauffeur PrenomChauffeur dateRecrutement

codeVoyage dateVoyage HeureDépart HeureArrivée villeDépart villeArrivée codeChauffeur codeVehicule

4.Dans la classe programme déclarer une liste de Voyages. 5.Ecrire une méthode qui affiche les voyages assurés par un chauffeur dont le nom est passé en paramètre. 6.Ecrire une méthode qui permet de reporter un voyage. 7.Ecrire une méthode qui permet de changer le véhicule affecté à un voyage. 8. Ecrire une méthode qui affiche les voyage affectés au véhicule 1234 l’année 2011.

Travail à faire :

1. Créer la classe véhicule avec les constructeurs, accesseurs et modificateurs

2. Créer la classe chauffeur avec les constructeurs, accesseurs et modificateurs

3. Créer la classe Voyage avec les constructeurs, accesseurs et modificateurs

45

Programmation orientée objet M.CHAKOUJ

9. Ecrire une méthode qui affiche les informations des chauffeurs recrutés ces 3 dernière année. 10. Ecrire une méthode qui affiche les voyages a destination de Agadir aujourd’hui. Exercice 5 : On désire réaliser un programme permettant de calculer les caractéristiques d’un cylindre de Rayon R et de Hauteur H. 1. Le programme est constitué d’une classe Cylindre contenant les méthodes suivantes : GetRayon() : Retourne le Rayon saisi par l’utilisateur GetHauteur() : Retourne la hauteur saisie par l’utilisateur CalculSurface() : Calcule la surface du cylindre (3.14*R*R) CalculSurfaceLaterale() : Calcule la surface latérale du cylindre (3.14*R*H) SurfaceTotale() : Calcule la surface totale du cylindre [3.14*R*(H+R)] Volume() : Calcule le volume du cylindre (3.14*R*R*H) 2. Écrire une méthode main, qui crée une instance de la classe cylindre , et qui demande à l’utilisateur de saisir le Rayon et la Hauteur et affiche ces caractéristiques.

46

Programmation orientée objet M.CHAKOUJ

I. Méthodes de lecture et d'écriture des attributs privés : Sont appelées aussi (accesseurs)(getters and setters). Nous rajoutons à la classe Personne les méthodes nécessaires pour lire ou modifier l'état des attributs des objets crées à l’extérieur de la classe :

Maintenant aller à la méthode Main() de la classe programme créer une instance p1 de la classe Personne .Pour affecter la chaine ‘’Hammadi’’ à son attribut nom (accès en écriture)on va utiliser SetNom() ,et pour l’afficher à l’écran (accès en lecture)on va utiliser GetNom().

Il existe une autre façon d'avoir accès aux attributs d'une classe, c'est de créer des propriétés. Celles-ci nous permettent de manipuler des attributs privés comme s'ils étaient publics .

Chapitre 5 : Accesseurs , Propriétés ,et membres static

47

Programmation orientée objet M.CHAKOUJ

II. Les propriétés Une propriété permet de lire (get) ou de fixer (set) la valeur d'un attribut. Une propriété est déclarée comme suit : Public Type NomPropriété { get {...} set {...} } où Type doit être le type de l'attribut géré par la propriété. La méthode get est habituellement chargée de rendre la valeur de l'attribut qu'elle gère (elle pourrait rendre autre chose, rien ne l'empêche). La méthode set reçoit un paramètre appelé value qu'elle doit affecter normalement à l'attribut qu'elle gère. Elle peut en profiter pour faire des Vérifications sur la validité de la valeur reçue et éventuellement lancer une exception (chapitre 9) si la valeur se révèle invalide. Prenons un exemple pour illustrer les propriétés. Le prix renseigné d’un produit (propriété Prix) est multiplié par deux quand la quantité en stock est inférieure à dix unités. La propriété présente l’avantage d’être aussi simple à utiliser qu’une variable, tout en ayant la puissance d’un appel de fonction. Ce sont aussi les propriétés qui permettent d’écrire des expressions telles que DateTime.Now.DayOfYear (nous en rencontrerons bien d’autres tout au long de ce policopie). Nous commenterons le programme par la suite :

using System; class Produit { public Produit(int q, int p) { m_Qtité = q; m_Prix = p; } public void Entrée(int qtité) { m_Qtité += qtité; } public void Sortie(int qtité) { m_Qtité -= qtité; } int m_Qtité; int m_Prix; // propriété Prix public int Prix { get { return m_Qtité<10 ? m_Prix*2 : m_Prix; } set { m_Prix = value; } } } Testons la propriété Prix : class Program { static void Main() { Produit p = new Produit(8, 100); p.Entrée(15); //15 produit en stock p.Sortie(10); // cinq produits en stock

48

Programmation orientée objet M.CHAKOUJ

Console.WriteLine("Prix unitaire actuel : " + p.Prix); } }

Prix est une propriété de la classe Produit. Lors de l’exécution de : n = p.Prix;//accès en écriture la fonction accesseur en lecture (partie get) de la propriété est automatiquement appelée et n prend la valeur renvoyée par cette fonction. Lors de l’exécution de : p.Prix = 50;//Accès en écriture la fonction d’accès en écriture (partie set) de la propriété est exécutée, avec value (mot réservé) qui prend automatiquement la valeur 50. Depuis la version 2, un accesseur de propriété peut être qualifié de protected ou de public (ce qui est le cas par défaut). Par exemple : class A { public string Prop { get { ..... } protected set { ..... } } } Il est possible de lire la propriété Prop d’un objet à partir de classes extérieures à A. La modification reste néanmoins possible à partir de fonctions membres de la classe A. C# version 3 (Visual Studio 2008) a dès lors introduit une syntaxe simplifiée, qui ne s’applique qu’à ce cas simple mais néanmoins courant : class Pers { public string Nom { get; set; } ..... } On parle dans ce cas de propriété auto-implémentée. Le compilateur génère automatiquement le champ privé correspondant à la propriété (mais celui-ci reste inaccessible par votre code C#) ainsi que les instructions (simples) correspondant au get et au set. Si vous avez besoin d’instructions plus élaborées (même uniquement dans le get ou le set), il vous appartient d’écrire la propriété « à l’ancienne ». Remarque : Une autre caractéristique des propriétés est qu'elles peuvent être utilisées conjointement avec un constructeur selon la syntaxe suivante : Classe objet=new Classe (...) {Propriété1=val1, Propriété2=val2, ...} Cette syntaxe est équivalente au code suivant : Classe objet=new Classe(...); objet.Propriété1=val1; objet.Propriété2=val2; ... Exemple : Personne p = new Personne () { _Nom="Ahmadi",_Prenom="salem",Age=25};

III. Les méthodes et attributs de classe : le mot clé static On veut compter les objets Véhicules créés par une application, pour se faire on doit inclure dans la classe un compteur nbVehicule comme attribut puis on l’incrémente à chaque création d’un nouveau instance (donc dans tous les constructeurs). Mais malheureusement à chaque création d’objet Véhicule l’attribut prend la valeur 1, tous ça est dû du faite que l’attribut nbVehicule est un attribut d’instance, pour remédier à ce

49

Programmation orientée objet M.CHAKOUJ

problème on doit déclarer nbVehicule comme attribut de classe (partagé par tous les instance crés de la classe) la syntaxe est la suivante: private static int nbVehicule;

Testons notre classe dans Main() :

50

Programmation orientée objet M.CHAKOUJ

L’attribut nbVehicule est appelé directement par la classe sans faire recours à une instanciation car il est déclaré par le mot clé static c’est un attribut de classe . La méthode societé() est appelée directement par la classe sans faire recours a une instanciation car elle est déclaré par le mot clé static c’est une méthode de classe.

En bref :

Un champ statique d’une classe : • existe indépendamment de tout objet de la classe et existe même si aucun objet de la classe n’a encore été créé ; • est partagé par tous les objets de la classe ; • est accessible par c.ch où c désigne le nom de la classe et ch le nom du champ statique (autrement dit par le nom de la classe suivi d’un point suivi du nom du champ) ; • peut être initialisé et manipulé dans une méthode de la classe comme c’est le cas pour n’importe quel champ. Une méthode statique peut être appelée même si aucun objet de la classe n’a encore été créé : appelez une telle méthode par X.g() (sans oublier les arguments) où X désigne le nom de la classe et g le nom de la méthode statique (WriteLine de la classe Console est un exemple de fonction statique).

51

Programmation orientée objet M.CHAKOUJ

Les méthodes statiques et non statiques doivent respecter les règles suivantes. • Une méthode statique n’a accès qu’aux champs statiques de sa classe ; . • Une méthode statique peut appeler une autre méthode statique (de sa classe ou d’une autre) mais ne peut pas appeler une méthode non statique. • Une méthode non statique d’une classe a accès à la fois aux champs statiques et aux champs non statiques de sa classe. Remarque : sin() et cos()…..sont des méthodes statiques de la classe Math,pour les appeler

Math.Sin(x) et Math.Cos(y)

52

Programmation orientée objet M.CHAKOUJ

Exercice 1 :

Un commerçant désire automatiser la gestion des commandes de ces clients. Il désire avoir la possibilité de mettre à jour quotidiennement ces commandes clients. Pour gérer les commandes, il a besoin des données citées ci-dessous :

1- Créer la classe Produit avec éventuellement des constructeurs et des accesseurs

a-Proposer une solution pour forcer le CodePro à être unique.

2- Créer la classe Commande avec éventuellement des constructeurs et des propriétés.

a-Proposer une solution pour forcer le NC à être unique.

b- la date de la commande est celle d’aujourd’hui.

3-Codage de la classe de test Program :

a. Créer un tableau contenant 4 produits. b. Créer une instance de la classe commande. c. La commande crée concerne les deux premiers produits avec les quantités respectives 123 et 222.

Créer les instances nécessaires de la classe DétailsCommande (à stocker dans un tableau). d. Calculer le montant de la commande en DH.

TP3

53

Programmation orientée objet M.CHAKOUJ

Exercice 2 :

on souhaite développer une application pour la gestion d’un club sportif. • Un adhérent peut s’inscrire pour pratiquer diverses disciplines (Natation, Musculation, Arts martiaux). • Lors de l’inscription, l’adhérent fournit les informations suivantes :

� Nom � Prénom � Adresse � Date de naissance � Code d’identification. (généré automatiquement par l’application) � Discipline(s) choisie (s).

• Toutes les disciplines sont définies par un code, un nom et une description. Travail à faire :

1) Développer une classe Adherent, avec les constructeurs adéquats, les propriétés, et une méthode d’affichage Affchei_adherent(….)

2) Développer une classe Disciplines, avec les constructeurs adéquats, les propriétés, et une méthode d’affichage Affchei_Disciplines(….)

3) Développer une méthode Saisie_Adherent(….) permettant de saisir au clavier les informations d’un nouveau adhérent et de l’ajouter à la liste des adhérents.

4)Développer une méthode Choix_Disciplines(….) permettant un à un adhérent donné, de choisir une au plusieurs disciplines. L’adhérent ne peut choisir que une des disciplines citées dans l’énoncé .

5)Ecrire une méthode qui calcule le nombre d’adhérent ayant choisis une discipline dont le code est passé en paramètre.

Exercice 3 :

54

Programmation orientée objet M.CHAKOUJ

6.Ecrire une méthode qui affiche les visites d’un patient (avec info patient)

7. Ecrire une méthode qui supprimer les rendez-vous dont la date est antérieure à aujourd’hui.

8. Ecrire une méthode qui affiche les rendez-vous d’aujourd’hui.

9. Ecrire une méthode qui affiche les rendez vous ratés ou annulés.

55

Programmation orientée objet M.CHAKOUJ

I. L’héritage

1. Définition :

L’héritage est une approche puissante pour la réutilisation du code. Comme toute technique de réutilisation, elle facilite la maintenance, améliore la productivité et permet de mieux structurer votre programme. L’héritage permet de construire une classe B à partir d’une classe existante A. Il s’agit d’une sorte d’héritage biologique. La classe B va ainsi hériter des variables, des méthodes, bref de tous les membres de A puis, on va ajouter des éléments supplémentaires propres à la classe B. Un héritage entre plusieurs classes fait naître une notion de hiérarchie. Si B hérite de A, on dit que B est une classe fille, une sous-classe, une classe enfant ou encore une classe dérivée de A. D’une autre manière, A se nomme la classe mère, la classe de base, la classe parent ou encore la super classe de B. On peut examiner une hiérarchie de classes de deux façons différentes. On peut choisir une vision par spécialisation/redéfinition. Dans ce cas, la classe B est vue comme un cas particulier de la classe A. Par exemple, un 4x4 est un cas particulier d’une Voiture. Dans cette vision, l’ensemble des Voitures est l’ensemble englobant et les 4x4 représentent un sous-ensemble des Voitures. Un autre point de vue est celui de l’extension. La classe B est vue comme une version étendue de la classe A. Par exemple, un 4x4 est une voiture disposant de 2 roues motrices supplémentaires. Du point de vue des fonctionnalités, la classe 4x4 englobe les fonctionnalités de la classe Voiture, la classe Voiture a moins de paramètres internes que la classe 4x4.

Les avantages majeurs de ce procédé étant la possibilité d’affiner vos classes tout en préservant l’intégrité des classes parentes, de capitaliser votre travail au fur et à mesure de vos développement en construisant vos librairies de classes (permettant ainsi de constituer votre framework). Règles : - Il ne peut y avoir qu’une seule classe parent. L’héritage multiple est interdit. - Les cycles sont interdits : A ne peut hériter de B si B hérite déjà de A.

2. Syntaxe :

Pour spécifier qu'une classe est dérivée d'une autre classe, utilisez la syntaxe suivante :

Classe NomclasseFille : NomClasseParente

Chapitre 6 : L’héritage et le polymorphisme

56

Programmation orientée objet M.CHAKOUJ

{ //Le code de la classe ClasseFille }

Exemple : //définition de la super classe Vehicule class Vehicule { Private string nom; public void Setnom(string nom){ this.nom=nom ;}; public void AfficheNom() { Console.WriteLine(nom); } } //définition de la classe dérivée Voiture class Voiture : Vehicule { //attribut en plus de ceux de Vehicule que Voiture possède Private int puissance ; public void Setpuissance(int puissance){ this.puissance=puissance ;}; //une deuxième méthode en plus de AfficheNom() public void Info() { Console.WriteLine(nom); Console.WriteLine(puissance); } } La classe programme : static void Main(string[] args) { //création d’un objet de la super classe Vehicule V = new Vehicule(); V.Setnom(‟Proto‟); V.AfficheNom(); //création d’un objet de la classe dérivée Voiture K = new Voiture(); K.Setnom (‟Buggy”); K.Setpuissance (4) ; K.Info() ; K.AfficheNom() ; } Attention :

57

Programmation orientée objet M.CHAKOUJ

Les instructions suivantes sont fausses et engendrent des erreurs : V.setpuissance( 4); V.Info(); car puissance et info()sont des membres de la classe dérivée, donc un objet de la super classe ne les possède pas. Remarque : -L’explorateur d’objets de VS2008 permet de voir la hiérarchie en classe de toute classe du framework .net -le mot clef sealed précédant le mot clef class permet d’empêcher l’extension d’une classe,en parle d’une classe sans héritière. -Pas d'héritage pour les structures: Dans .NET Framework les classes-structures de type valeur sont déclarées comme structures et ne sont pas dérivables. - X is Voiture // renvoie true si X est du type Voiture -soit l’instruction suivante : Français f = Conjoint as Français; if (f != null) ..... // il s’agit d’un Français Le mot réservé as effectue une tentative de transtypage de Conjoint (défini de type Personne) en Français (classe dérivée de Personne). Si la tentative réussit (parce que le conjoint est effectivement un Français), f prend une valeur non nulle et fait référence au conjoint. Sinon, f prend la valeur null.

3. Constructeurs et chaînage

Le constructeur de la sous-classe appelle toujours celui de la classe de base, implicitement ou explicitement. Si rien n'est spécifié, le compilateur génère un appel implicite au constructeur de la classe de base ne comportant aucun paramètre. C'est pourquoi ce constructeur est nommé « constructeur par défaut ». Si la classe de base ne possède aucun constructeur par défaut, ou si un autre serait plus approprié, il est possible de spécifier explicitement le constructeur à appeler. Le mot-clé base désigne la classe de base. Prenons une classe Employe enfant d’une classe Personne. Lors de l’écriture de ses constructeurs paramétriques ou sans arguments de la classe Employe, on doit se poser la question de comment va-t-on gérer la construction des éléments provenant de Personne. Exemple :

Soit la classe Employe dérivée de la classe Personne :

58

Programmation orientée objet M.CHAKOUJ

Le mot clef « base » sert à appeler explicitement le constructeur de la classe mère de Employe. Le constructeur de la classe parent fait ce qu’il doit faire : vérification / affectation / initialisation des attribut nom,prenom,age et nous faisons dans le constructeur de Employe uniquement ce qui concerne la classe Employe (c'est-à-dire l’initialisation de l’attribut salaire). Question : dans quel ordre sont lancés les constructeurs ? class A { public A() { WriteLine(“construction de A”); } } class B : A { public B() : base() { WriteLine(“construction de B”); } } L’instruction : B toto = new B() ; Engendre l’affichage suivant : construction de A construction de B Le constructeur de la classe parent est lancé AVANT les instructions du constructeur de la classe B. Si la classe A possède un parent, son constructeur sera appelé avant que celui de A soit exécuté. Au final, c‟est le constructeur du parent initial dans la hiérarchie qui sera le premier lancé, puis ceux de ses enfants successivement. Ce comportement logique provient du fait que pour fonctionner, la classe B peut nécessiter des ressources venant de sa classe mère. Attention : Lors de la construction de B, le fait que le constructeur de A soit appelé ne veut pas dire qu’un objet de type A est créé mais que les membres hérités de A dans B sont initialisés. Au final, il n’y a bien qu’un seul objet de type B de créé.

4. Référence d'instance

Une référence à une instance de la sous-classe peut être stockée par une référence du même type : Employe Emp1 = new Employe(); Il est également possible d'utiliser une référence du type de la classe de base : Personne Emp2 = new Employe(). Q) Quelles différences ?

II. polymorphisme

59

Programmation orientée objet M.CHAKOUJ

1. Principe

Le terme polymorphisme désigne la capacité d’une méthode à pouvoir prendre un comportement différent suivant le contexte (les types utilisés). Ainsi nous pouvons obtenir des implémentations plus générales, mieux structurées et plus simples à comprendre. Ainsi une fonction peut exister sous le même nom dans une hiérarchie mais avoir un comportement différent suivant le type de l’objet instancié. On parle alors de polymorphisme d’héritage.

2. Mise en place

Le polymorphisme d’héritage est garanti si l’on utilise une syntaxe particulière. La première classe où la méthode est déclarée pour la première fois (la super classe)doit porter le qualificatif virtual et toutes les classes enfants modifiant son comportement doivent précéder sa déclaration par le qualificatif override. class A { public virtual void Aff() { WriteLine(“Bonjour“); } } class B : A { } class C : B { public override void Aff() { WriteLine(“Coucou“); } } class D : C { } Remarques : Rem 1 : le mot clef override est obligatoire pour redéfinir une fonction virtuelle. Rem 2 : on peut utiliser le mot clef final pour empêcher toute redéfinition.

3. Chainage des redéfinitions

Il est toujours possible d’appeler la fonction qui a été redéfinie à partir de la redéfinition avec le mot clé base. Cela permet de construire des chaines de fonctions dans le même principe que le chainage des constructeurs. Par exemple, supposons que la classe Voiture dispose d’une fonction TestAllumage() qui vérifie que tous les composants électriques (ordinateur de bord, ABS, ESP, air bag, ...) de la voiture fonctionnent bien. Dans le cas d’un Cabriolet qui ajoute un toit amovible, il faudra contrôler l’ensemble des systèmes d’une voiture simple et le système qui rentre/sort le toit amovible. class Cabriolet : Voiture { public override void TestAllumage() { base() ; // test des éléments de la classe Voiture par appel a TestAllumage() de Voiture testToitAmovible() ; // test des éléments spécifiques au Cabriolet ... } } Exemple : public class Vehicule { private int poids; public Vehicule(int poids) { this.poids = poids; } public virtual string Description() { return "Véhicule de "+poids+" tonnes"; } }

60

Programmation orientée objet M.CHAKOUJ

Et il faut utiliser le mot clé override dans la classe dérivée : public class Automobile : Vehicule { private string couleur; public Automobile(int poids,string couleur) : base(poids) { this.couleur = couleur; } // méthode surchargée public override string Description() { return base.Description()+" de couleur "+couleur; } } Utilisation : Vehicule vehicule = new Automobile(3, "rouge"); Console.WriteLine( vehicule.Description() ); // affiche : Véhicule de 3 tonnes de couleur //rouge Si le mot clé new est utilisé à la place du mot clé override, le polymorphisme n'est pas effectif.

61

Programmation orientée objet M.CHAKOUJ

Exercice 1 : Soit les classes suivantes :

Créer les classes : Personnel et Enseignant, sachant que la classe Enseignant hérite de la classe Personnel. Ajouter des constructeurs et des propriétés . 2.Ajouter une méthode afficher() qui affiche dans une ligne les informations relatives à un personnel 3.Redéfinir la méthode toString() dans la super classe Personnel,et dans la sous classe Enseignant. 4.Redéfinir la méthode afficher() dans la sous classe Enseignant. 5.Créer les classes Etudiant et Module avec éventuellement des constructeur et des propriétés 6.Ajouter une méthode permettant de calculer le salaire Net à payer pour un Enseignant donnée, sachant que : SalaireNet = [SalaireBrut + (NbreheuresSup * Taux_horaire)] * (1 - Taux_IGR) Exercice 2 :

TP4

62

Programmation orientée objet M.CHAKOUJ

63

Programmation orientée objet M.CHAKOUJ

I. Classe abstraite :

1. Le mot clé abstract et méthode abstraite :

Le mot clef abstract est utilisé pour représenter une classe ou une méthode abstraite. L’intérêt de cette notion et d’avoir des modèles génériques permettant de définir ultérieurement des actions spécifiques. Une méthode déclarée en abstract dans une classe : • N'a pas de corps de méthode. • N'est pas exécutable. • Doit obligatoirement être redéfinie dans une classe fille. Une méthode abstraite n'est qu'une signature de méthode sans implémentation dans la classe. En C#, les méthodes abstraites sont automatiquement virtuelles, elles ne peuvent être déclarées que public ou protected, enfin elles doivent être redéfinies avec le qualificateur override.

2. Classe abstraite :

Une classe abstraite est une classe non instanciable . Il faut créer des classes dérivées qui elles pourront être instanciées. On peut utiliser des classes abstraites pour factoriser le code d'une lignée de classes.

Exemple :

//la classe abstraite Etre_Vivant

abstract class Etre_Vivant { //la méthode abstraite SeDeplacer( ) public abstract void SeDeplacer( ); } //classe Serpent dérivant de la classe Etre_Vivant class Serpent : Etre_Vivant { //Implémentation de la méthode SeDeplacer( ) public override void SeDeplacer( ) { //....en rampant Console.WriteLine(‘’je me déplace en rampant’’) ; } } //autre classe fille class Oiseau : Etre_Vivant { public override void SeDeplacer( ) { //.....en volant Console.WriteLine(‘’je me déplace en volant’’) ; } } //autre classe fille class Homme : Etre_Vivant { public override void SeDeplacer( ) { //.....en marchant

Chapitre 7 : Classe abstraite et Interface

64

Programmation orientée objet M.CHAKOUJ

Console.WriteLine(‘’je me déplace en marchant’’) ; }

}

Remarques :

1- une classe abstraite ne peut pas être instanciée, ce qui ne l’empêche pas de posséder un ou plusieurs constructeurs appelés par le mécanisme de chaînage des constructeurs. 3 -une classe non abstraite fille d’une classe abstraite doit implémenter toutes les méthodes abstraites de sa classe mère. 4 -vous pouvez créer une sous-classe abstraite d’une classe (abstraite ou non). Dans tous les cas, il faudra alors qualifier explicitement cette sous classe d’abstraite. 5- une classe dérivée qui redéfinit toutes les méthodes abstract de la classe mère sauf une (ou plus d'une) ne peut pas être instanciée et subit la même règle que la classe mère : elle contient au moins une méthode abstraite donc elle est aussi une classe abstraite et doit donc être déclarée en abstract. 6- Une classe abstract peut contenir des méthodes non abstraites et donc implantées dans la classe.

II. Interfaces : Une interface est un ensemble de prototypes de méthodes ou de propriétés qui forme un contrat. Une classe qui décide d'implémenter une interface s'engage à fournir une implémentation de toutes les méthodes définies dans l'interface. C’est le compilateur qui vérifie cette implémentation. Une interface est définie de manière similaire à une classe mais elle ne contient que des prototypes de fonctions sans qualificateur de visibilité. C’est la classe implémentant l’interface qui choisit leurs visibilités. Une classe peut hériter de plusieurs interfaces et dans ce cas nous avons une excellente alternative à l'héritage multiple. Exemple : interface IVehicule { void Demarrer( ); void RépartirPassager( ); void PériodicitéMaintenance( ); } //Une classe abstraite implémentant cette interface : class Terrestre : IVehicule { public void Demarrer( ){ //le code ici }; public void RépartirPassager( ){ //le code ici } public void PériodicitéMaintenance( ){ //le code ici ….. } } Comparaison entre une interface et une classe abstraite : � Les interfaces ressemblent aux classes abstraites sur un seul point : elles contiennent des membres

expliquant certains comportements sans les implémenter. � Les classes abstraites et les interfaces se différencient principalement par le fait qu'une classe peut

65

Programmation orientée objet M.CHAKOUJ

implémenter un nombre quelconque d'interfaces, alors qu'une classe abstraite ne peut hériter que d'une seule classe abstraite ou non.

66

Programmation orientée objet M.CHAKOUJ

Exercice 1 :

5.Dans la classe de test :

a. Est –il possible de créer une instance de la classe Equipement ?expliquer votre réponse. b. Ecrire une méthode menu() qui propose à l’utilisateur de :

1. Créer un ordinateur. 2. Créer une table. 3. Créer une chaise. 4. Quiter.

Exercice 2 : Ecrire le code correspondant à ce diagramme de classes :

TP5

67

Programmation orientée objet M.CHAKOUJ

Exercice 3 : Construction d'une hiérarchie d'interface et implémentation dans une classe concrète. On donne la hiérarchie d'interfaces suivante :

Toutes les propriétés sauf une, sont en lecture et en écriture (la propriété isAdulte est en lecture seulement). On se propose d'implémenter l'interface IBaleine avec la classe BaleineBosses :

Question : Construire la classe BaleineBosses en sachant que :

• Une baleine à bosse met 11 mois pour devenir adulte (valeur à ranger dans la constante publique moisPourAdulte )

• Chaque propriété est rangée dans un champ privé auquel la propriété accède en lecture et en écriture. • La méthode age(int nbrMois) range l'âge de l'animal en mois dans un champ privé nommé etatAge et

positionne la propriété isAdulte à true ou à false selon que l'âge est plus grand ou plus petit que moisPourAdulte.

68

Programmation orientée objet M.CHAKOUJ

69

Programmation orientée objet M.CHAKOUJ

Quand vous développez des applications, vous pouvez avoir besoin de traiter et stocker de nombreuses données en continu. L’utilisation des tableaux statiques pouvant être fastidieuse et peu optimisée, le Framework .NET implémente les collections, ces classes conteneurs sont des classes qui permettent d’implémenter des tableaux dynamiques (qui s’agrandissent automatiquement), des piles, des listes chaînées éventuellement triées, etc. Les classes de collections se trouvent dans l’espace du nom : System.Collections.

Toutes les collections s'appuient sur l'interface ICollection (directement ou indirectement). Dans les collections qui s'appuient sur l'interface IList (comme par exemple Array, ArrayList ou List) ou directement sur l'interface ICollection (comme par exemple Queue, Stackou LinkedList), chaque élément contient une valeur uniquement. Dans les collections reposant sur l'interface IDictionary (telles que les classes Hashtable et SortedList, ou les classes génériques Dictionary et SortedList), chaque élément contient à la fois une clé et une valeur. La classe KeyedCollection est unique parce qu'il s'agit d'une liste de valeurs avec clés incorporées dans les valeurs ; par conséquent, elle se comporte comme une liste et comme un dictionnaire.

I. La classe ArrayList :

1. Définition :

La classe System.Collections.ArrayList permet de créer des collections d’objets simple, dont la taille s’adapte automatiquement au nombre d’objets, et possédant un index. Elle hérite de la classe object et implémente les interfaces IList, ICollection, IEnumerable, ICloneable ( public class ArrayList : IList, ICollection, IEnumerable, ICloneable;) Remarque: Notez que l’espace de noms System.Collections (donc le using correspondant) n’est pas généré par défaut par Visual Studio, contrairement à System.Collections.Generic (vraisemblablement une incitation à l’utilisation des génériques).

2. Méthodes : Les principales méthodes permettant de manipuler les éléments d'un ArrayList sont :

Chapitre 8 : Les collections

70

Programmation orientée objet M.CHAKOUJ

Exemple : On va travailler avec la classe personne élaborer en premier chapitre.

71

Programmation orientée objet M.CHAKOUJ

Remarque : 1-Un objet de classe ArrayList peut "grandir" automatiquement d'un certain nombre de cellules pendant l'exécution, c'est le programmeur qui peut fixer la valeur d'augmentation du nombre de cellules supplémentaires dès que la capacité maximale en cours est dépassée. Dans le cas où la valeur d'augmentation n'est pas fixée, c'est la machine virtuelle du CLR qui procède à une augmentation par défaut. 2-Vous pouvez utiliser le type ArrayList avec n'importe quel type d'objet puisqu'un ArrayList contient des éléments de type dérivés d'object (qui la classe mère de toute classe ). 3- La capacité initiale par défaut de ArrayList est 0. Lorsque des éléments sont ajoutés à ArrayList, la capacité augmente automatiquement par réallocation. La capacité peut être diminuée en appelant TrimToSize ou en définissant explicitement la propriété Capacity. 4-les limitations de ArrayList: Premièrement, nous pouvions mélanger n’importe quel type d’objet dans la liste, des entiers, des voitures, des chiens,etc. Cela devenait une classe fourre-tout et nous ne savions jamais ce qu’il y avait dans la liste. Deuxièmement, même si nous savions qu’il n’y avait que des entiers dans la liste, nous étions obligés de le traiter en tant qu’object et donc d’utiliser le boxing et l’unboxing pour mettre les objets dans la liste ou pour les récupérer.

Cela engendrait donc confusion et perte de performance. Grâce aux génériques, il devenait donc possible de créer des listes de n’importe quel type et nous étions certains du type que nous allions récupérer dans la liste.

II. La classe générique 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 Lis est-il noté Lis[i]. Exemple 1 :

Regardons cet exemple :

72

Programmation orientée objet M.CHAKOUJ

La première ligne permet de créer la liste d’entiers. Nous ajoutons des entiers à la liste grâce à la méthode Add(). Nous ajoutons en l’occurrence les entiers 8, 9 et 4. La méthode RemoveAt() permet de supprimer un élément en utilisant son indice, ici nous supprimons le deuxième entier, c’està- dire 9. Enfin, nous parcourons les éléments de la liste grâce à l’instruction foreach.

a. Exemple 2 :

73

Programmation orientée objet M.CHAKOUJ

Exercice :

Le code suivant provoquera une erreur (pourquoi ? proposez une solution) :

List<string> jours = new List<string> { "Lundi", "Mardi","Mercredi", "Jeudi", "Vendredi", "Samedi", "Dimanche" }; foreach (string jour in jours) { jour = "pas de jour !" ;}

b. Exemple 3 :

74

Programmation orientée objet M.CHAKOUJ

3. Traiter des objets (le tri) :

a. En implémentant l’interface IComparable Soit un tableau de Personne (de type Pers), pour pouvoir le trier une première technique consiste à implémenter l’interface IComparable dans cette classe Pers. L’interface IComparable ne comporte qu’une seule méthode : CompareTo() qui compare deux objets (celui sur lequel opère la fonction et celui qui est passé en argument). CompareTo() renvoie 0 si les deux objets sont semblables (ici, même nom et même âge), et une valeur positive si le premier est supérieur au second. Dans notre cas, on compare d’abord les noms et, si les noms sont identiques, les âges. Implémenter l’interface IComparable pour Pers revient à nous obliger à implémenter la fonction CompareTo() dans Pers. La méthode Sort de la classe Array appellera cette méthode pour comparer deux personnes.

using System; class Pers : IComparable { public string Nom { get; set; } public int Age { get; set; } public override string ToString() {return Nom + " (" + Age + ")";} int IComparable.CompareTo(object o)

75

Programmation orientée objet M.CHAKOUJ

{ Pers op = (Pers)o; int res = Nom.CompareTo(op.Nom); if (res == 0) res = Age - op.Age; return res; } } class Program { static void Main() { Pers[] tp = {new Pers{Nom="Prunelle", Age=35}, new Pers{Nom="Jeanne", Age=23}, new Pers{Nom="Gaston", Age=27}, new Pers{Nom="Prunelle", Age=5} }; Array.Sort(tp); foreach (Pers p in tp) Console.WriteLine(p); } }

b. En définissant une classe de comparaison implémentant l’interface IComparer : Si l’on ne dispose pas du code source de la classe Pers (puisqu’il faut faire implémenter l’interface IComparer à Pers)il faut créer une classe implémentant l’interface IComparer (interface définie dans System.Collections). L’interface IComparer ne comporte qu’une seule méthode : Compare.

using System; using System.Collections; class Pers { public string Nom { get; set; } public int Age { get; set; } public override string ToString() {return Nom + " (" + Age + ")";} } class ComparePers : IComparer { public int Compare(object o1, object o2) { Pers op1=(Pers)o1, op2=(Pers)o2; int res = op1.Nom.CompareTo(op2.Nom); if (res == 0) res = op1.Age - op2.Age; return res; } } class Program { static void Main() { Pers[] tp = {new Pers{Nom="Prunelle", Age=35}, new Pers{Nom="Jeanne", Age=23}, new Pers{Nom="Gaston", Age=27}, new Pers{Nom="Prunelle", Age=5} }; Array.Sort(tp, new ComparePers());

76

Programmation orientée objet M.CHAKOUJ

foreach (Pers p in tp) Console.WriteLine(p); } }

III. Autres classes de collections : La liste est la classe générique que vous utiliserez sûrement le plus. Mais beaucoup d’autres sont à votre disposition. Citons par exemple la classe Queue<> qui permet de gérer une file d’attente style FIFO (first in, first out : premier entré, premier sorti) :

Citons encore le dictionnaire d’élément qui est une espèce d’annuaire où l’on accède aux éléments grâce à une clé :

77

Programmation orientée objet M.CHAKOUJ

Tandis que la classe Stack fourni une collection d'objets non plus sous forme de file mais sous forme de pile. En effet, dans ce type de collection, nous ne pouvons ajouter des objets que via la méthode Push qui empile un objet en haut de la pile et ne pouvons retirer des objets que via la méthode Pop qui va dépiler le dernier objet qui a été posé sur le tas. Le schéma ci-contre récapitule le comportement d'une pile.

Note : Un index permet, dans un tableau ou dans une collection, d’accéder plus facilement aux données. La première position de l’index est 0 ! Voici un tableau récapitulatif :

78

Programmation orientée objet M.CHAKOUJ

Pour découvrir les membres de la classe List, voir le lien suivant : http://msdn.microsoft.com/fr-fr/library/d9hw1as6%28v=vs.80%29

79

Programmation orientée objet M.CHAKOUJ

Exercice 1 : 1/ Créer la classe Elève. � Attributs : Numéro, Nom, Prénom, Adresse, Section, Moyenne.

� Méthodes : � Constructeur par défaut.

� Constructeur d’initialisation.

� Affiche.

� Accesseurs (Pour chaque attribut)

� Modifieurs (Pour chaque attribut) 2/ Créer la classe Ecole qui contient : � Une liste d’élèves

� Les méthodes :

� Ajouter (ajouter un élève).

� Modifier (modifier un élève donné par son numéro).

� Supprimer

� Liste_Admis (qui affiche liste des élèves admis).

� Liste_Section (qui affiche liste des élèves en donnant la section). 3/ Créer un programme qui le menu suivant : (déclarer un objet de type Ecole)

N.B : Utiliser l’objet List pour la création de la liste

Exercice 2 :Ecrire le code correspondant à ce diagramme de classes :

TP 6

80

Programmation orientée objet M.CHAKOUJ

81

Programmation orientée objet M.CHAKOUJ

Exercice 3 :

82

Programmation orientée objet M.CHAKOUJ

83

Programmation orientée objet M.CHAKOUJ

I. Exceptions : Une exception est chargée de signaler un comportement exceptionnel (mais prévu) d’une partie spécifique d’un logiciel. Dans les langages de programmation actuels, les exceptions font partie du langage lui-même. C’est le cas de C# qui intègre les exceptions comme une classe particulière: la classe Exception. Cette classe contient un nombre important de classes dérivées.

II. Gérer une exception ? Dès qu’une erreur se produit comme un manque de mémoire, un calcul impossible, un fichier inexistant, un transtypage non valide,..., un objet de la classe adéquate dérivée de la classe Exception est instancié. Nous dirons que le logiciel " déclenche une exception ".

1. Programme sans gestion de l'exception

Soit un programme C# contenant un incident d'exécution (une division par zéro dans l'instruction x = 1/0; ) dans la méthode meth() de la classe Action1, cette méthode est appelée dans la classe UseAction1 à travers un objet de classe Action1 :

Lors de l'exécution, après avoir affiché les chaînes "Début du programme" et " ...Avant incident", le programme s'arrête et l'environnement d'exécution commun (CLR ou Common Language Runtime) signale une erreur. Voici ci-dessous l'affichage obtenu dans VS 2008:

Chapitre 9: Gestion des exceptions

84

Programmation orientée objet M.CHAKOUJ

Sur la console l'affichage est le suivant :

Le programme s'est arrêté à cet endroit et ne peut plus poursuivre son exécution. Dès que l'instruction "x = 1/0;" a été exécutée celle-ci a provoqué un incident. En fait une exception de la classe DivideByZeroException a été "levée" (un objet de cette classe a été instancié) par le CLR, cette classe hérite de la classe ArithmeticException selon la hiérarchie d'héritage suivante de .Net Framework : System.Object |__System.Exception |__System.SystemException |__System.ArithmeticException |__System.DivideByZeroException Remarque : l’héritage sera traiter dans le chapitre suivant. La classe mère de toutes les exceptions de .Net Framework est la classe Exception. Le CLR a arrêté le programme immédiatement à cet endroit parce qu'elle n'a pas trouvé de code d'interception de cette exception qu'il a levée automatiquement. C# possède une instruction qui permet d'intercepter des exceptions dérivant de la classe Exception : try ... catch

2. Attraper une exception

Un gestionnaire d'exception attrape une classe d'exception particulière et gère le cas d'erreur correspondant. Ce gestionnaire encadre les instructions à gérer pouvant lancer une exception. La syntaxe est la suivante :

85

Programmation orientée objet M.CHAKOUJ

try { // Une exception peut être lancée

instructions } catch ( classe_d_exception variable ) {

// Gérer l'erreur en fonction des détails

// de l'erreur contenus dans la variable instructions

} ...autres blocs catch...

finally { // Instructions toujours exécutées

// Exception lancée ou non instructions }

Le bloc try est suivi d'un nombre quelconque de bloc catch (éventuellement aucun) attrapant différents types d'exception, et éventuellement d'un bloc finally qui sera toujours exécuté quoi qu'il se passe.

3. Programme avec gestion de l'exception :

Soit le même programme C# que précédemment, contenant un incident d'exécution (une division par zéro dans l'instruction x = 1/0; ). Cette fois nous allons gérer l'incident grâce à un gestionnaire d'exception try..catch dans le bloc englobant immédiatement supérieur.

86

Programmation orientée objet M.CHAKOUJ

Ci-dessous l'affichage obtenu sur la console lors de l'exécution de ce programme :

Nous remarquons que le CLR a donc bien exécuté le code d'interception situé dans le corps du "catch (DivideByZeroException ){...}", il a poursuivi l'exécution normale après le gestionnaire. • Le gestionnaire d'exception se situe dans la méthode Main (code englobant) qui appelle la méthode meth( ) qui lève l'exception. Il est aussi possible d'atteindre l'objet d'exception qui a été instancié (ou levé) en déclarant un identificateur local au bloc catch du gestionnaire d'exception try … catch, cet objet est disponible dans tout le corps de la clause catch. Dans l'exemple qui suit, on déclare un objet Except de classe DivideByZeroException et l'on lit le contenu de deux de ses propriétés Message et Source : try { Obj.meth(); } catch ( DivideByZeroException Except ) { // accès aux membres publiques de l'objet Except :

87

Programmation orientée objet M.CHAKOUJ

Console.WriteLine("Interception exception message : " + Except.Message); Console.WriteLine("Interception exception source : " + Except.Source); …. } Dans un gestionnaire try...catch, il est en fait possible d'intercepter plusieurs types d'exceptions différentes et de les traiter. Ci-après nous montrons la syntaxe d'un tel gestionnaire qui fonctionne comme un sélecteur ordonné, ce qui signifie qu'une seule clause d'interception est exécutée. Dès qu'une exception intervient dans le < bloc de code à protéger>, le CLR scrute séquentiellement toutes les clauses catch de la première jusqu'à la nième. Si l'exception actuellement levée est d'un des types présents dans la liste des clauses le traitement associé est effectué, la scrutation est abandonnée et le programme poursuit son exécution après le gestionnaire.

4. Libération des ressources avec finally :

Un bloc finally est utile pour libérer des ressources à la fin d'un traitement, qu'une erreur ait eu lieu ou non. Par exemple si vous écrivez une méthode qui ouvre un fichier.Si vous traitez l’accès à votre fichier dans le bloc try,vous pouvez attraper des exceptions relatives à l’ouverture, lecture, écriture dans le fichier .A la fin du code vous aurez besoin à fermer le fichier malgré que l’exception est levée. Vous allez donc placer l’instruction de fermeture de fichier dans le boc finally.

III. Lancer une exception Il est possible de déclencher soi-même des exceptions en utilisant l'instruction throw , voir même de déclencher des exceptions personnalisées ou non. Une exception personnalisée est une classe héritant de la classe System.Exception définie par le développeur lui-même. La syntaxe est la suivante : throw objet_exception; Où objet_exception est une instance de la classe Exception ou de l'une de ses sous-classes. En général, l'objet exception est alloué en même temps qu'il est lancé : throw new classe_exception(arguments);

1. Lancer une exception prédéfinies de C#.

Le CLR peut aussi lever (déclencher) une exception à votre demande suite à la rencontre d'une instruction throw . Le programme qui suit lance une ArithmeticException (ie: instancie un objet de type ArithmeticException) avec le message "Mauvais calcul !" dans la méthode meth( ) et intercepte cette exception dans le bloc englobant Main . Le traitement de cette exception consiste à afficher le contenu du champ message de l'exception grâce à la propriété Message de l'exception :

88

Programmation orientée objet M.CHAKOUJ

2. Déclenchement manuel d'une exception personnalisée :

Pour une exception personnalisée, le mode d'action est strictement identique, il vous faut seulement auparavant créer une nouvelle classe héritant obligatoirement de la classe Exception ou de n'importe laquelle de ses sous-classes. Reprenons le programme précédent et créons une classe d'exception que nous nommerons ArithmeticExceptionPerso héritant de la classe des ArithmeticException puis exécutons ce programme : // notre classe ArithmeticExceptionPerso class ArithmeticExceptionPerso : ArithmeticException { public ArithmeticExceptionPerso( String s) : base (s) { } } //la classe qui contient la méthode lançant une exception ArithmeticExceptionPerso //avec un message personnaliser class Action1 { public void meth()

89

Programmation orientée objet M.CHAKOUJ

{ int x= 0; Console .WriteLine( " ...Avant incident" ); if (x == 0) throw new ArithmeticExceptionPerso ( "Mauvais calcul !" ); Console .WriteLine( " ...Après incident" ); } } //La classe programme class Program { static void Main( string [] args) { Action1 Obj = new Action1 (); Console .WriteLine( "Début du programme." ); try { Obj.meth(); } catch ( ArithmeticExceptionPerso E) { Console .WriteLine( "Interception ArithmeticException : " + E.Message); } Console .WriteLine( "Fin du programme." ); Console .ReadLine();} } Résultat d’exécution :

L'exécution de ce programme est identique à celle du programme précédent, notre exception personnalisée fonctionne bien comme les exceptions prédéfinies de C#.

90

Programmation orientée objet M.CHAKOUJ

Exercice 1 : Soit une classe Employé ayant comme attributs : matricule,nom,prénom,age,echelle,genre (F ou H). -Une exception AgeException sera déclanchée si en essai d’affecter à l’age une valeur non non comprise entre 18 et 100 ; -Une exception nommée EchelleException sera levér si l’echelle n’est pas compri entre 5 et 30. -Une execption GenreException sera levée si le gernre est différent de F et H. -Une execption MatriculeException sera levée si on tente d’ajouter à la liste des employés un employé ayant un matricule déjà affecté. Travail à faire : 1-Ecrire le code de la classe Employé avec les propriétés , et les constructeurs. 2- Ecrire les codes des classes d’exceptions citées ci-dessus. 3- Dans la classe Program : -Déclarer une collection d’employés. -créer 4 instances de la classe Employé,et ajouter ceux-ci à la collection(les données seront demandées à l’utilisateur ). 4- Gérer ces exceptions. Exercice 2 : L’objectif est de Construire une classe de nombres rationnels à partir de la traduction en diagramme UML du TAD de rationnel. Une classe de rationnels implantera l'interface IRatio contenant la méthode Reduire ( ) l'objet rationnel :

La classe Rationnel :

TP7

91

Programmation orientée objet M.CHAKOUJ

Les 2 propriétés Denom et Num représente respectivement le dénominateur et le numérateur du rationnel, elles sont rangées dans les champs privés FDenom et FNum. Reduire ( ) : rendre le rationnel irréductible en calculant le pgcd du numérateur et du dénominateur, puis diviser ces deux termes par le pgcd. pgcd ( int a, int b ) : renvoie le pgcd de deux entiers non nuls. ppcm ( int a, int b ) : renvoie le ppcm de deux entiers non nuls. Normalise ( ) : normalisation du signe du rationnel, soit dénominateur toujours positif et seul le numérateur est signé. operator +, -, /, * : opérations classiques sur les rationnels. ToString ( ) : renvoie le rationnel sous forme d'une fraction avec une barre "/" ( ex : 3/5 )

La classe Rationnel sera rendue robuste par l'utilisation d'une classe d'exception rationnelException :

Des exceptions seront lancées dans les deux cas suivants : La création d'un rationnel à dénominateur nul comme new Rationnel ( 5 , 0 ) déclenchera une rationnelException avec comme message :

La mise à la valeur 0 du dénominateur d'un rationnel r ( r.Denom = 0 ) déclenchera une rationnelException avec comme message :

92

Programmation orientée objet M.CHAKOUJ

I. Définitions :

La sérialisation consiste à rendre un objet susceptible d’être enregistré sur disque ou d’être transmis à une autre machine via une ligne de communication. La désérialisation consiste à créer et initialiser un objet à partir d’informations provenant d’un fichier. La sérialisation permet aussi de passer des objets d’une machine à l’autre.

II. Sérialisation et désérialisation : � Pour sérialiser un objet, il suffit de :

1. Marquer la classe de l’objet avec l’attribut [Serializable]. 2. Créer un objet BinaryFormatter ainsi qu’un objet FileStream pour créer un fichier. 3. Exécuter Serialize. � Pour désérialiser l’objet, c’est-à-dire l’instancier en mémoire à partir d’une lecture sur disque, il faut :

1. Créer un objet BinaryFormatter ainsi qu’un objet FileStream pour lire un fichier. 2. Exécuter Deserialize appliqué à l’objet BinaryFormatter. Exemple : Pour sérialiser (dans le fichier objPers.dat du répertoire courant mais peu importent le nom et l’extension) un objet de la classe Pers : // sérialiser dans le fichier objPers l’objet p de la classe //Pers Pers p = new Pers ( "Gaston" , 25); BinaryFormatter formatter = new BinaryFormatter (); FileStream fs = new FileStream ( "objPers.txt" , FileMode .OpenOrCreate, FileAccess .Write); formatter.Serialize(fs, p); fs.Close(); Sur disque, on trouve maintenant un objet Pers contenu dans le fichier objPers.dat. Pour créer l’objet en mémoire à partir d’une lecture dans ce fichier objPers.dat : //Désérialiser BinaryFormatter formatter2 = new BinaryFormatter (); FileStream fsdes = new FileStream ( "objPers.dat" , FileMode .Open, FileAccess .Read); Pers pdes = ( Pers )formatter2.Deserialize(fsdes); Console .WriteLine(pdes); fsdes.Close(); On retrouve dans p.Nom et p.Age les informations enregistrées lors de la sérialisation de l’objet (ici sérialisation dans le fichier objPers.dat). Rien ne nous empêche de sérialiser une collection d’objets (il pourrait s’agir d’une liste génériques: ArrayList al = new ArrayList(); Pers p = new Pers ( "Gaston" , 25); al.Add(p); p = new Pers ( "Jeanne" , 23); al.Add(p); // sérialiser la collection (ici un tableau dynamiq ue d’objets Pers) BinaryFormatter formatter = new BinaryFormatter (); FileStream fs = new FileStream ( "objListe.dat" , FileMode .OpenOrCreate, FileAccess .Write); formatter.Serialize(fs, al); fs.Close(); Pour désérialiser la collection ainsi enregistrée sur disque dans le fichier objListe.dat : BinaryFormatter formatter = new BinaryFormatter ();

Chapitre 10 : La Sérialisation binaire

93

Programmation orientée objet M.CHAKOUJ

FileStream fs = new FileStream ( "objListe.dat" , FileMode .Open, FileAccess .Read); ArrayList al = (ArrayList)formatter.Des erialize(fs); fs.Close(); Attention : La sérialisation consiste à convertir tout (ou une partie) des valeurs des attributs d’une classe. Le code des méthodes ou des propriétés n’est pas sérialisé. • Un sérialiseur sérialise par défaut des types primitifs. Si la classe à sérialiser contient des champs faisant référence à d’autres types complexes (non primitifs :des classes) il faudra alors définir ces autres types comme sérialisable. Exercice : 1-Utiliser la sérialisation pour coder la méthode Exporter() vue dans le projet Gestion d’inventaire. 2- Utiliser la désérialisation pour coder la méthode Editer() qui permet d’afficher le contenu du fichier associé à une administration. Solution de l’exercice :Sérialisation et désérialisation public void exporter() { //le fichier concernat l'administration courante se ra créer dans le bureau string s = "C:\\Users\\chakouj\\Desktop\\" +this .nom+ ".txt" ; BinaryFormatter formatter = new BinaryFormatter (); FileStream fs = new FileStream (s, FileMode .OpenOrCreate, FileAccess .Write); formatter.Serialize(fs, ls); fs.Close(); } public void Editer() { string s = "C:\\Users\\chakouj\\Desktop\\" +this .nom+ ".txt" ; BinaryFormatter formatter = new BinaryFormatter (); FileStream fs = new FileStream (s, FileMode .Open, FileAccess .Read); List <Site > al = ( List <Site >)formatter.Deserialize(fs); Console .WriteLine( "le ficher " + s+ " contient : " ); foreach ( Site site in al) { Console .WriteLine(site.ToString()); Console .WriteLine( "Les équipements " ); foreach ( Equipement eq in site.le) Console .WriteLine(eq.ToString()); Console .WriteLine( "------------------- " ); } fs.Close(); }

94

Programmation orientée objet M.CHAKOUJ

Chapitre 11 : Type nullable,type var,type dynamic,Regex,using

I. Les types nullable :

1-Intorduction : C# version 2 a introduit les types nullables (nullable types en anglais) pour répondre à la question suivante : comment signaler qu’un contenu de variable ne correspond à rien ? Ce concept est bien connu et est largement utilisé depuis de nombreuses années dans le domaine des bases de données (contrainte signalant qu’un champ de table peut avoir une valeur nulle). Dans le cas d’objets, c’est simple : on lui donne la valeur nulle (mot réservé null dans la référence). Mais pour les types valeurs (int, float, etc. ainsi que les structures), la réponse est plus compliquée.

2.Syntaxe : On peut créer une telle variable (ici un int nullable) en écrivant : Nullable<int> i1=1; Nullable<int> i2=null; // ou bien : int? i2 = new Nullable<int>(); Nullable<int> i3; i1 est de type Nullable<int>, avec HasValue qui vaut true et Value qui vaut 1. i2 est de type Nullable<int>, avec HasValue qui vaut false. i3, comme toute variable, ne pourra être utilisée qu’après initialisation à une valeur entière ou à null(sinon le compilateur détecte l’utilisation d’une variable non assignée). Déclarer i3 sans l’initialiser n’a pas pour effet d’initialiser sa propriété HasValue à false ! La propriété HasValue de i3 ne pourra donc être lue qu’après initialisation de i3. Cette syntaxe étant assez lourde, on peut écrire de manière tout à fait équivalente : int? i1=1; int? i2=null; int? i3;

Quelles opérations peut-on effectuer sur ces variables ? Considérons les variables suivantes : int i=1, j=2; int? ni=10, nj=null;

95

Programmation orientée objet M.CHAKOUJ

II. Le type var : C# version 3 (VS 2008) a introduit le type var. Avec var, nous laissons au compilateur le soin de déterminer le véritable type d’un objet. Le véritable type de la variable est déterminé dès la compilation, d’après la valeur d’initialisation. Le type de la variable ne peut être modifié par la suite. Le compilateur ne fait donc que substituer un véritable type à var. Au lieu d’écrire (en supposant que la classe Pers existe et que ..... remplacent des initialisations de propriétés) : Pers p = new Pers { ..... }; int q = 15; string s = "Hello"; on peut écrire : var p = new Pers { ..... }; var q = 15; var s = "Hello"; Le compilateur détermine automatiquement que les types de p, q et s sont respectivement Pers, int etstring en fonction des valeurs d’initialisation (en déclarant une variable de type var, il faut donner une valeur

96

Programmation orientée objet M.CHAKOUJ

d’initialisation). p, q et s garderont ce type tant que ces variables restent en vie. Ces types ne pourront jamais être modifiés suite à une assignation d’un autre type dans p, q et s (il en résulterait une erreur de compilation). var n’est applicable qu’aux objets déclarés localement dans une fonction (on ne peut donc pas trouver var dans une définition de classe).

III. Le type dynamic : C# version 4 (Visual Studio 2010) a pour cela introduit le type dynamic, qui signifie : « pas de type définitivement associé à une variable de type dynamic ». Le véritable type, à un moment donné, d’une variable (car une variable doit avoir un type, à un moment donné) est déterminé en cours d’exécution par du code évidemment supplémentaire injecté par le compilateur dans le programme (et non plus lors de la compilation de celui-ci) et peut varier à tout moment, en fonction des assignations effectuées dans cette variable. Par exemple (en supposant que Pers soit une classe déjà déclarée et sans reprendre ses valeurs d’initialisation) : dynamic x; // type de x inconnu à ce stade x = 10; // x maintenant de type entier x = "Bonjour"; // x maintenant de type string x = new Pers { ..... }; // x maintenant de type Pers La variable x passe, en cours d’exécution, par les types int, string et Pers, en fonction des opérations effectuées sur x.

XV. Les expressions régulières : System.Text.RegularExpressions 1. Utilisation :

Les Regex sont un outil (ou plutôt un système) très puissant permettant de vérifier la syntaxe d'une chaîne de caractères. Plus précisément, c'est vérifier que la chaîne de caractères à examiner respecte un motif ou une série de motifs (notre Regex) désignant la syntaxe attendue de la phrase. Les Regex sont utilisées pour trois grands types d'action : - Vérifier la syntaxe(forme) d'une chaîne de caractères (ex : adresse ip de forme chiffre.chiffre.chiffre.chiffre) - Remplacer une partie de la chaîne (token) par un élément spécifique - Découper une chaîne de caractères

2. Syntaxe Les Regex sont donc une suite de motifs qui se composent de métacaractères, de classes sous .NET et d'alias. Voici tout d'abord, une série de métacaractères pouvant être utilisés et ayant chacun une correspondance bien précise.

97

Programmation orientée objet M.CHAKOUJ

Ces métacaractères nous permettent donc de faire des combinaisons infinies pouvant correspondre à tous les besoins.

Néanmoins, pour vérifier des chaînes de caractères de taille importante, l'écriture de ces métacaractères peut être

fastidieuse, en plus du fait que la chaine Regex n'est pas très lisible pour le developpeur. Heureusement, il existe une

série d'alias permettant de faciliter cette tâche :

3. Exemples

Comme rien n'est plus parlant qu'un exemple concret, en voici quelque-uns qui démontrent à quel point les chaînes Regex peuvent être simples... ou complexes :) Chaîne qui contient des lettres de a à d : [a-d] ou [abcd] Chaîne qui contient des lettres de a à d ou n'importe quelles lettres majuscules : [a-dA-Z] Chaîne commençant (et finissant) par y ou z : ^(y | z)$ Chaîne ne contenant pas de chiffre : [^0-9] Chaîne contenant les chiffres 1 ou 2 ou le symbole ^ : [12\^] On peut utiliser plusieurs métacaractères : ^[pP]hara(onix)?$ : phara, Phara, pharaonix ou Pharaonix Ou tout simplement vérifier la validité d'une adresse ip : ^(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}$ Note: Cette ligne de validation semble complexe mais dans une application, elle est la seule alternative à une suite énorme de substring() et comparaisons via les méthodes traditionnelles.

4. Utilisation en .Net Les Regex nécessitent l'utilisation de l'espace de noms System.Text.RegularExpressions.

a. Validation d'une chaîne

La validation d'une chaîne de caractères se fait grâce à la méthode IsMatch() qui retourne une valeur booléenne égale à true si la chaîne correspond à la Regex et false dans le cas contraire. Voici comme exemple, la méthode ValidMail() vérifie la validité d'une adresse mail passée en paramètre.

private bool ValidMail(string adresse)

98

Programmation orientée objet M.CHAKOUJ

{ System.Text.RegularExpressions.Regex myRegex = new Regex(@"^([\w]+)@([\w]+)\.([\w]+)$"); //([\w]+) ==> caractère alphanumérique apparaissant une fois ou plus return myRegex.IsMatch(adresse); // retourne true ou false selon la vérification }

b. Remplacement dans une chaîne Une deuxième utilité des Regex est de pouvoir rechercher des occurrences de chaînes spécifiques et de les remplacer par une autre chaîne. Dans ce cas précis, nous utiliserons la méthode Replace(). Celle-ci est plus ou moins identique à la méthode Replace() de l'objet string, mais cette dernière ne permet de remplacer qu'une seule chaîne de caractères par une autre. Prenons comme exemple, la méthode, SMS qui s'assure de remplacer certains termes par d'autres: Sélectionnez private string SMS(string chaine) { System.Text.RegularExpressions.Regex myRegex = new Regex("(lut|salut|yop)"); return myRegex.Replace(chaine,"bonjour"); //renvoi la chaine modifiée } Cette fois ci, notre méthode remplacera toutes les occurrences des mots " lut ", " salut " et " yop " par le mot "bonjour".

c. Découpage d’une chaine par séparateur

Grâce aux Regex, il est également possible de découper une chaîne de caractères de différentes manières. La première méthode est la méthode Split() qui génère un tableau de chaînes de caractères en découpant une chaîne de départ via un séparateur : mais ici, nous pouvons déclarer des séparateurs dynamiques. Voici comme exemple, la méthode Splitter() qui découpe une chaîne caractères en plusieurs chaînes dont les séparateurs sont des chiffres

Sélectionnez

private string[] Splitter(string chaine) { Regex myRegex=new Regex(@"\d+"); return myRegex.Split(chaine); } En lui passant la chaîne "Voici3234un2exemple23423427de2chaîne3424de767caractères"; elle renverra un tableau contenant {Voici, un, exemple, de, chaîne, de, caractères}

XVI. Le porté d’un objet et la clause using :

Le ramasse-miettes (ou garbage collector) est un processus intégré dans le .NET Framework permettant de libérer automatiquement la mémoire lorsqu’un objet n’est plus

99

Programmation orientée objet M.CHAKOUJ

utilisé. Il est cependant très difficile de prévoir à quel moment le ramasse-miettes se mettra à fonctionner. Certaines classes contiennent des ressources, telle une connexion à une base de données qu’il faut libérer dès que l’objet n’est plus utilisé. Si le ramasse-miettes met du temps à se déclencher, la connexion à la base de données risque d’être libérée tardivement. Le bloc using de C# permet de protégé un objet implémentant l’interface IDisposable. Lors de la sortie de ce bloc, la méthode Dispose()(de libération) de l’objet protégé est automatiquement appelée. using (EcritureFichier f = new EcritureFichier()) { f.EcritureFichier();

} L’objet f peut être utilisé seulement à l’intérieur des accolades.

100

Programmation orientée objet M.CHAKOUJ

1. Laboratoire auto-formation Rm di Scala 2. C# et .NET Versions 1 à 4 G é r a r d L e b l a n c 3. Polycopie programmation orienté objet Mr.A Ben Daoud. 4. Le site http://msdn.microsoft.com/fr-fr/library est le site de référence pour accéder à la documentation officielle de C# et du .NET Framework. Le site http://social.msdn.microsoft.com/forums/fr-fr/categories est un ensemble de forums consacrés aux développements des technologies Microsoft.

5. http://www.developpez.com 6. C# 4 Développez des applications Windows avec Visual Studio 2010 Jérôme HUGON

Ressources bibliographiques :

101

Programmation orientée objet M.CHAKOUJ

Annexe :Liste mots clès en C#

Si vous avez besoin d’utiliser un mot clé en tant qu’identifiant pour un membre, il faut préfixer le nom de l’identifiant par le caractère @.