IFT 1179 : Programmation en C#
A) Héritage :
La POO favorise la réutilisation des classes, des méthodes, du codage. Grâce à l'héritage, on peut modifier une classe sans avoir à la réécrire complètement .
Héritage simple : une classe peut hériter d'une seule classe de base
classe Triangle avec 3 côtés (côté1, côté2, côté3)
Triangle rectangle Triangle isocèle
Triangle équilatéral (3 côtés égaux)
Un triangle équilatéral est un triangle isocèle.
Un triangle isocèle est aussi un triangle.
etc . . .
Héritage multiple: une classe peut hériter de plus d'une classe de base
classe Informaticien
Analyste Programmeur
AnalysteProgrammeur
Un analyste-programmeur est à la fois un analyste et un programmeur.
La classe AnalysteProgrammeur hérite de deux classes de base : Analyste et Programmeur, c’est l’héritage multiple.
Ce concept est permis en C++ mais non en C# ni en Java. Comme Java, le C# utilise la notion de l'interface (matière vers la semaine 10) pour contourner une partie de ce problème.
Veuillez noter qu’au début de l’enseignement de la POO avec C++, pour programmer une liste linéaire des personnes, on a utilisé souvent l’héritage multiple :
Liste Personne
ListePersonne
Depuis le bon développement de la librairie standard STL de C++, on a utilisé plutôt list<Personne> au lieu d’utiliser l’héritage multiple.
Le but pratique de l’héritage est la ré-utilisation du codage. Une sous-classe peut disposer de champs, de méthodes supplémentaires mais profite aussi des champs des méthodes de sa classe de base.
Exemple 1 : classe Rectangle et quelques sous-classes d’elle
classe Rectangle
champs : longueur, largeur qq constructeurs
méthodes : Surface, ToString
RectangleVisible Champ supplément.
Redéfinir ToString
Carre
Pas de champ Méthode supp.
Redéfinir ToString
RectangleColore
Champ supplément.
Méthode supp.
Redéfinir ToString
Veuillez faire attention avec le saut de page de Word
/* Fichier Heritage1.cs * Introduction à l'héritage */
using System;
class Rectangle {
protected double longueur, largeur;
public Rectangle(double longueur, double largeur) {
this.longueur = longueur;
this.largeur = largeur;
Console.WriteLine("On appelle le constructeur a deux parametres de Rectangle");
}
public Rectangle(double cote): this(cote, cote)
{ Console.WriteLine("On appelle le constructeur a un parametre de Rectangle");
}
public Rectangle() : this(5.0, 4.0) {
}
public double Surface() {
return longueur * largeur ; }
public static bool operator < (Rectangle rect1, Rectangle rect2) {
return rect1.Surface() < rect2.Surface();
}
public static bool operator > (Rectangle rect1, Rectangle rect2) {
return rect1.Surface() > rect2.Surface();
}
public override string ToString()
{ Console.WriteLine("On appelle le ToString() de Rectangle");
return string.Format("{0, 6:F2} {1, 8:F2} {2, 10:F3} ", longueur, largeur, Surface());
}
public void Afficher() {
Console.WriteLine("Rectangle : <{0, 8:F2}, {1, 8:F2}, {2, 8:F2}>", longueur, largeur, Surface());
}
} // fin Rectangle
class Carre : Rectangle {
public Carre(double cote): base(cote) {
Console.WriteLine("On appelle le constructeur de Carre");
}
public double Diagonale() {
return longueur * Math.Sqrt(2.0);
}
public override string ToString() {
return "En tant que rectangle : " + base.ToString()
+ "\n" + "Comme carre : diagonale = " + Diagonale() + "\n";
}
public void Afficher() {
Console.WriteLine("Carre : <{0, 8:F2}, {1, 8:F2}, {2, 8:F2}, {3, 8:f2}>",
longueur, largeur, Surface(), Diagonale());
}
}
class RectangleVisible : Rectangle {
private bool estVisible;public RectangleVisible(double lo, double la, bool estVisible) : base(lo, la)
{ this.estVisible = estVisible;
Console.WriteLine("On appelle le constructeur de RectangleVisible");
}
public override string ToString() {
return "En tant que rectangle : " + base.ToString()
+ "\n" + "ESt-il visible? - " + estVisible + "\n";
}
public void Afficher() {
Console.WriteLine("Rectangle visible : <{0, 8:F2}, {1, 8:F2}, {2, 8:F2}, {3}>",
longueur, largeur, Surface(), estVisible);
}
}
class RectangleColore : Rectangle {
private bool estColore;
public RectangleColore(double lo, double la, bool estColore) : base(lo, la)
{
this.estColore = estColore;
Console.WriteLine("On appelle le constructeur de RectangleColore");
}
public double Perimetre() {
return 2 * (longueur + largeur);
}
public override string ToString() {
return "En tant que rectangle : " + base.ToString() + "\n" + "ESt-il colore ? - " + estColore + "\n";
}
public void Afficher() {
Console.WriteLine("Rectangle colore : <{0, 8:F2}, {1, 8:F2}, {2, 8:F2}, {3, 8:f2}, {4}>",
longueur, largeur, Surface(), Perimetre(), estColore);
}
}
class Heritage1 {
static void Demo1() {
Console.WriteLine("--- Premiere demonstration : ---\n");
Rectangle rect = new Rectangle(12.8, 9.2);
Console.WriteLine("Infos de rect : " + rect);
Carre c = new Carre(4.5);
Console.WriteLine("Infos du carre c :\n" + c);
Console.WriteLine("c.Surface() vaut : " + c.Surface());
RectangleVisible rv = new RectangleVisible(6.2, 4.5, false);
Console.WriteLine("Infos du rectangle rv :\n" + rv);
RectangleColore rc = new RectangleColore(6.2, 4.5, true);
Console.WriteLine("Infos du rectangle rc :\n" + rc);
Console.WriteLine("Fin de la premiere demonstration :\n\n");
}
static void Afficher(Rectangle[] rect, string mess) {
double somSurface = 0.0;
Console.WriteLine("\nInfos du tableau des rectangles rect "
+ mess + ":\n");
for (int i = 0; i < rect.Length ; i++) { somSurface += rect[i].Surface();
Console.Write("{0, 3:D}) ", i);
rect[i].Afficher();
}
Console.WriteLine("\nLa surface totale : " + somSurface);
Console.WriteLine();
}
static void Demo2() {
Console.WriteLine("--- Deuxieme demonstration : ---\n");
Rectangle[] rect = { new Rectangle(10.2, 6.4), new Rectangle(),
new Rectangle(7.2),
new RectangleVisible(10.2, 6.4, true), new RectangleColore(7.8, 4.2, false), new Carre(8.3) };
Afficher(rect, "apres la declaration et l'initialisation");
Console.WriteLine("Fin de la deuxieme demonstration :\n\n");
}
static void Main(string[] args) {
Demo1();
Demo2();
} }
/* Execution:
--- Premiere demonstration : ---
On appelle le constructeur a deux parametres de Rectangle On appelle le ToString() de Rectangle
Infos de rect : 12,80 9,20 117,760
On appelle le constructeur a deux parametres de Rectangle On appelle le constructeur a un parametre de Rectangle On appelle le constructeur de Carre
On appelle le ToString() de Rectangle Infos du carre c :
En tant que rectangle : 4,50 4,50 20,250 Comme carre : diagonale = 6,36396103067893
c.Surface() vaut : 20,25
On appelle le constructeur a deux parametres de Rectangle On appelle le constructeur de RectangleVisible
On appelle le ToString() de Rectangle Infos du rectangle rv :
En tant que rectangle : 6,20 4,50 27,900 ESt-il visible? - False
On appelle le constructeur a deux parametres de Rectangle On appelle le constructeur de RectangleColore
On appelle le ToString() de Rectangle Infos du rectangle rc :
En tant que rectangle : 6,20 4,50 27,900 ESt-il colore ? - True
Fin de la premiere demonstration :
--- Deuxieme demonstration : ---
On appelle le constructeur a deux parametres de Rectangle On appelle le constructeur a deux parametres de Rectangle On appelle le constructeur a deux parametres de Rectangle On appelle le constructeur a un parametre de Rectangle On appelle le constructeur a deux parametres de Rectangle On appelle le constructeur de RectangleVisible
On appelle le constructeur a deux parametres de Rectangle On appelle le constructeur de RectangleColore
On appelle le constructeur a deux parametres de Rectangle On appelle le constructeur a un parametre de Rectangle On appelle le constructeur de Carre
Infos du tableau des rectangles rect apres la declaration et l'initialisation:
0) Rectangle : < 10,20, 6,40, 65,28>
1) Rectangle : < 5,00, 4,00, 20,00>
2) Rectangle : < 7,20, 7,20, 51,84>
3) Rectangle : < 10,20, 6,40, 65,28>
4) Rectangle : < 7,80, 4,20, 32,76>
5) Rectangle : < 8,30, 8,30, 68,89>
La surface totale : 304,05
Fin de la deuxieme demonstration :
Press any key to continue
*/
Champ protégé (clause
protected) :Un champ privé est accessible seulement, à l’intérieur de cette classe.
(c’est un peu égoïste : comme une voiture appartient seulement aux parents).
Dans un tel cas, pour profiter d’un champ privé, on devrait avoir des méthodes d’accès (get) ou des propriétés.
La POO propose aussi la clause "protected" : un champ protégé est aussi accessible dans ses classes dérivées.
Appel d’un constructeur d’une classe de base
:Un constructeur d’une sous-classe puisse appeler un constructeur d’une classe de base :
a) public Carre(double cote): base(cote) { . . .
le constructeur de la classe Carre appelle le constructeur à un seul paramètre de sa classe de base (Rectangle) pour construire un carré en tant qu’un rectangle.
b) public RectangleVisible(double lo, double la, bool estVisible)
: base(lo, la) { . . .
le constructeur de la classe RectangleVisible appelle le constructeur à deux paramètres de sa classe de base (Rectangle) pour construire un rectangle visible, d’abord comme un rectangle, avant de déterminer le champ visible.
méthode d’une classe dérivée vs de la classe de base
:Quand on est dans une sous-classe, c’est naturel qu’on a le droit d’utiliser des méthodes publique de la classe de base. Par contre, si on dispose d’une méthode qui porte le même nom avec la classe de base : cas de ToString() et la méthode Afficher
a) si vous souhaitez d’utiliser la méthode qui porte le même nom dans la classe de base, on écrit :
base.méthode( . . . ) (cas de ToString dans cet exemple)
b) le cas de la méthode Afficher est spécial : lors de l’exécution, on aperçoit que l’affichage ne réflète pas le cas des objets de sous-classes. On parlera de ce cas plus tard.
B) Boxing (emboîtage) et Unboxing (déboîtage) :
En C ou C++ :
double z = 12.3456;
int abc = z;
abc vaut 12 (valeur tronquée de z).
Le C# ne permet pas de cette conversion implicite.
On devrait programmer, par exemple :
double z = 12.3456;
int abc = (int) z;
C’est la conversion forcée.
On a déjà vu ce genre de conversion avec la redéfinition de equals :
Station autre = (Station) obj;
En C#, des types comme int, double, bool, ... sont des
types de valeurs (value types). Par contre string, des
classes inventées par nous, ... sont des types de référence
(reference types). Le C# est tout objet et considère que
des types de base sont associés aux classes (System.Int32,
System.String, . . .) dont hérités de object, la classe au
sommet de l’hiérarchie des classes.
Boxing (emboîtage) est la conversion implicite d’une valeur de type simple au type object (type de référence).
Unboxing (déboîtage) est la conversion explicite d’un valeur emboîtée au type de base.
Exemple :
int age = 25;
bool estAdulte ;
object obj = age; // boxing
estAdulte = ((int) obj) >= 18;
---
unboxing
Console.WriteLine("estAdulte vaut : " + estAdulte);
L’exécution donne :
estAdulte vaut : True Press any key to continue
Exemple complet :
Veuillez faire attention avec le saut de page de Word
/* Fichier BoxUnbox.cs
* Boxing (emboîtage) et unboxing (déboîtage) *
* object (assoicé à Object) est la classe au sommet de * l'hiérarchie des classes
*/
using System;
class BoxUnbox {
// Style classique de boxing et unboxing en C#
static void Demo1() {
Console.WriteLine("Premiere demonstration : Boxing et UnBoxing");
object obj;
int age = 23;
obj = age; // boxing
Console.WriteLine("obj vaut {0}", obj);
int nbCafe = (int) obj % 10; // unboxing
Console.WriteLine("{0} tasses de cafe par jour", nbCafe);
string chaine = "Bonsoir";
obj = chaine; // boxing
Console.WriteLine("obj vaut {0}", obj);
string souhait = (string) obj + " tout le monde!";
// unboxing
Console.WriteLine("{0}", souhait);
double taille =1.72;
obj = taille; // boxing
Console.WriteLine("obj vaut {0}", obj);
double taille2 = (double) obj + 0.05; // unboxing Console.WriteLine("taille2 vaut {0} metre", taille2);
}
// paramètres par défaut et variables
static void Afficher(params object[] tableau) {
Console.WriteLine("Nombre de parametres a l'appel : {0}", tableau.Length);
foreach (object param in tableau)
Console.WriteLine("{0}", param);
Console.WriteLine();
}
static void Demo2() {
Console.WriteLine("\nDeuxieme demonstration :");
Afficher(); // aucun paramètre int age = 25; double taille = 1.72;
Afficher(age, taille); // deux paramètres string souhait = "Bonne session!";
Afficher(souhait); // un seul paramètre
}
// compter le nombre de personnes d'un sexe voulu
static int LeNombre( char[] sexe, params object[] obj) {
char sexeVoulu = obj.Length == 1 ? 'F':'M';
int n = 0;
for (int i = 0; i < sexe.Length; i++) if (sexe[i] == sexeVoulu)
n++;
return n;
}
static void Demo3() {
Console.WriteLine("\nTroisieme demonstration :");
char[] sexe = {'F', 'M', 'M', 'F', 'F', 'F' };
Console.WriteLine("\nLe nombre d'hommes : {0}",
LeNombre(sexe, 'M'));
Console.WriteLine("\nLe nombre de femmes : {0}",
LeNombre(sexe)); // 2ième paramètre par défaut Console.WriteLine();
}
static void Demo4() {
Console.WriteLine("\nQuatrieme demonstration :");
object[] infos = new object[] { 23, 65.2, "Tremblay Martin"};
// string est un type de reference string nomPre = infos[2] as string;
Console.WriteLine("\nSon nom et prenom : " + nomPre);
Console.WriteLine();
}
static void Main(string[] args) {
Demo1();
Demo2();
Demo3();
Demo4();
} } /* Execution:
Premiere demonstration : Boxing et UnBoxing obj vaut 23
3 tasses de cafe par jour obj vaut Bonsoir
Bonsoir tout le monde!
obj vaut 1,72
taille2 vaut 1,77 metre
Deuxieme demonstration :
Nombre de parametres a l'appel : 0
Nombre de parametres a l'appel : 2 25
1,72
Nombre de parametres a l'appel : 1 Bonne session!
Troisieme demonstration : Le nombre d'hommes : 4 Le nombre de femmes : 2 Press any key to continue
*/
La compréhension de Boxing et Unboxing est assez facile pour cet exemple. Les autres notions vues dans cet exemple sont expliquées en bas.
Paramètres par défaut ou de types variables :
Observez les 3 appels suivants d’une même méthode :
Afficher(); // aucun paramètre int age = 25; double taille = 1.72;
Afficher(age, taille); // deux paramètres string souhait = "Bonne session!";
Afficher(souhait); // un seul paramètre
On observe qu’à l’appel :
- le nombre de paramètres est différent (0, 2 puis 1) - le type des paramètres est différent
int (age) vs string (souhait)
Cette realisation est possible grâce au paramètre de type tableau des objects et la clause «params» :
static void Afficher(params object[] tableau) {
Console.WriteLine("Nombre de parametres a l'appel : {0} ", tableau.Length);
foreach (object param in tableau)
Console.WriteLine("{0}", param);
Console.WriteLine();
}
Le mot clé
params
signale qu’un argument peut être une liste des arguments séparés par des virgules de même type ou un tableau. Cette clause params devrait être sur le dernier argument d’une liste des arguments (c’est un style de philosophie du C++).static void Demo2() {
Console.WriteLine("\nDeuxieme demonstration :");
Afficher(); // aucun paramètre int age = 25; double taille = 1.72;
Afficher(age, taille); // deux paramètres string souhait = "Bonne session!";
Afficher(souhait); // un seul paramètre
}
Un autre exemple :
static double Moyenne(params double[] tableau) { double somme = 0.0;
int nbElem = tableau.Length;
foreach (double valeur in tableau) somme += valeur;
return somme / nbElem;
}
static void Main(string[] args) {
double[] taille = { 1.72, 1.78, 1.75 },
poids = { 85.4, 100.2, 79.8, 94.6 };
Console.WriteLine("La taille moyenne : " + Moyenne(taille) + " metre");
Console.WriteLine("Le poids moyen : " + Moyenne(poids) + " kg");
Console.WriteLine("Le salaire hebdo moyen : " + Moyenne(1000.00, 2000.00, 1500.00) + " $");
}
Exécution :
La taille moyenne : 1,75 metre Le poids moyen : 90 kg
Le salaire hebdo moyen : 1500 $ Press any key to continue
Fonction virtuelle, redéfinition (overriding):
Avec l'héritage, il est utile, dépendant des besoins, de redéfinir des méthodes existantes d'une super-classe. C'est le cas des deux méthodes toString() et equals qui sont souvent redéfinies dans la plupart des sous-classes d'Object .
Dans l’exemple Heritage1.cs, lors de son exécution pour la deuxième démonstration , on
a obtenu l’affichage suivante :
. . .
Infos du tableau des rectangles rect apres la declaration et l'initialisation:
0) Rectangle : < 10,20, 6,40, 65,28>
1) Rectangle : < 5,00, 4,00, 20,00>
2) Rectangle : < 7,20, 7,20, 51,84>
3) Rectangle : < 10,20, 6,40, 65,28>
4) Rectangle : < 7,80, 4,20, 32,76>
5) Rectangle : < 8,30, 8,30, 68,89>
La surface totale : 304,05
Fin de la deuxieme demonstration :
On constate que seulement la méthode Afficher() de la classe de base Rectangle est convoquée.
Par contre, si on remplace la méthode Afficher de Demo2 par :
static void Afficher( string mess, Rectangle[] rect) {
Console.WriteLine("\nInfos du tableau des rectangles rect " + mess + ":\n");
for (int i = 0; i < rect.Length ; i++) // utilisation de ToString() :
Console.WriteLine("{0, 3:D}) {1}", i, rect[i]);
Console.WriteLine();
}
on obtient l’exécution suivante :
Infos du tableau des rectangles rect apres la declaration et l'initialisation:
On appelle le ToString() de Rectangle 0) 10,20 6,40 65,280
On appelle le ToString() de Rectangle 1) 5,00 4,00 20,000
On appelle le ToString() de Rectangle 2) 7,20 7,20 51,840
On appelle le ToString() de Rectangle
3) En tant que rectangle : 10,20 6,40 65,280 ESt-il visible? - True
On appelle le ToString() de Rectangle
4) En tant que rectangle : 7,80 4,20 32,760 ESt-il colore ? - False
On appelle le ToString() de Rectangle
5) En tant que rectangle : 8,30 8,30 68,890 Comme carre : diagonale = 11,7379725676967
C'est-à-dire la bonne méthode ToString() est appliquée sur le bon Objet (un carré ou un rectangle ou un rectangle visible ou . . .)
Pourquoi a-t-on ce problème ?
C’est le cas aussi du langage C++ : le typage «statique» (à la
compilation). Comme rect est déclaré comme un tableau des Rectangle(s), Si on ne fait rien de spécial, une méthode de Rectangle (ici Afficher) sera appliquée. Pourque le typage soit déterminé à l’exécution au lieu à la compilation :
1) on déclare la méthode dans la classe de base est virtuelle 2) on redéfinit avec la clause override dans les sous-classes C’est le cas de la méthode ToString qui est virtuelle dans Object et qu’elle est redéfinie dans les sous-classes d’Object.
/* Introduction à la fonction virtuelle */
using System;
class Rectangle {
protected double longueur, largeur;
public Rectangle(double longueur, double largeur) {
this.longueur = longueur;
this.largeur = largeur;
Console.WriteLine("On appelle le constructeur a deux parametres de Rectangle");
}
public Rectangle(double cote): this(cote, cote) {
Console.WriteLine("On appelle le constructeur a un parametre de Rectangle");
}
public Rectangle() : this(5.0, 4.0) {
}
public double Surface() {
return longueur * largeur ; }
public static bool operator < (Rectangle rect1, Rectangle rect2) {
return rect1.Surface() < rect2.Surface();
}
public static bool operator > (Rectangle rect1, Rectangle rect2) {
return rect1.Surface() > rect2.Surface();
}
public override string ToString() {
Console.WriteLine("On appelle le ToString() de Rectangle");
return string.Format("{0, 6:F2} {1, 8:F2} {2, 10:F3} ", longueur, largeur, Surface());
}
public
virtual
void Afficher() {Console.WriteLine("Rectangle : <{0, 8:F2}, {1, 8:F2}, {2, 8:F2}>",
longueur, largeur, Surface());
} }
class Carre : Rectangle {
public Carre(double cote): base(cote) {
Console.WriteLine("On appelle le constructeur de Carre");
}
public double Diagonale() {
return longueur * Math.Sqrt(2.0);
}
public override string ToString() {
return "En tant que rectangle : " + base.ToString()
+ "\n" + "Comme carre : diagonale = " + Diagonale() + "\n";
}
public
override
void Afficher() {Console.WriteLine("Carre : <{0, 8:F2}, {1, 8:F2}, {2, 8:F2}, {3, 8:f2}>",
longueur, largeur, Surface(), Diagonale());
} }
class RectangleVisible : Rectangle {
private bool estVisible;
public RectangleVisible(double lo, double la, bool estVisible) : base(lo, la)
{
this.estVisible = estVisible;
Console.WriteLine("On appelle le constructeur de RectangleVisible");
}
public
override
string ToString() {return "En tant que rectangle : " + base.ToString()
+ "\n" + "ESt-il visible? - " + estVisible + "\n";
}
public override void Afficher() {
Console.WriteLine("Rectangle visible : <{0, 8:F2}, {1, 8:F2}, {2, 8:F2}, {3}>",
longueur, largeur, Surface(), estVisible);
} }
class RectangleColore : Rectangle {
private bool estColore;
public RectangleColore(double lo, double la, bool estColore) : base(lo, la)
{
this.estColore = estColore;
Console.WriteLine("On appelle le constructeur de RectangleColore");
}
public double Perimetre() {
return 2 * (longueur + largeur);
}
public override string ToString() {
return "En tant que rectangle : " + base.ToString() + "\n" + "ESt-il colore ? - " + estColore + "\n";
}
public
override
void Afficher() {Console.WriteLine("Rectangle colore : <{0, 8:F2}, {1, 8:F2}, {2, 8:F2}, {3, 8:f2}, {4}>",
longueur, largeur, Surface(), Perimetre(), estColore);
}
}
class Virtuel1 {
static void Demo1() {
Console.WriteLine("--- Premiere demonstration : ---\n");
Rectangle rect = new Rectangle(12.8, 9.2);
Console.WriteLine("Infos de rect : " + rect);
Carre c = new Carre(4.5);
Console.WriteLine("Infos du carre c :\n" + c);
Console.WriteLine("c.Surface() vaut : " + c.Surface());
RectangleVisible rv = new RectangleVisible(6.2, 4.5, false);
Console.WriteLine("Infos du rectangle rv :\n" + rv);
RectangleColore rc = new RectangleColore(6.2, 4.5, true);
Console.WriteLine("Infos du rectangle rc :\n" + rc);
Console.WriteLine("Fin de la premiere demonstration :\n\n");
}
static void Afficher(Rectangle[] rect, string mess) {
double somSurface = 0.0;
Console.WriteLine("\nInfos du tableau des rectangles rect "
+ mess + ":\n");
for (int i = 0; i < rect.Length ; i++) {
somSurface += rect[i].Surface();
Console.Write("{0, 3:D}) ", i);
rect[i].Afficher();
}
Console.WriteLine("\nLa surface totale : " + somSurface);
Console.WriteLine();
}
static void Afficher( string mess, Rectangle[] rect) {
Console.WriteLine("\nInfos du tableau des rectangles rect "
+ mess + ":\n");
for (int i = 0; i < rect.Length ; i++)
Console.WriteLine("{0, 3:D}) {1}", i, rect[i]);
Console.WriteLine();
}
static void Demo2() {
Console.WriteLine("--- Deuxieme demonstration : ---\n");
Rectangle[] rect = { new Rectangle(10.2, 6.4), new Rectangle(),
new Rectangle(7.2),
new RectangleVisible(10.2, 6.4, true), new RectangleColore(7.8, 4.2, false), new Carre(8.3) };
Afficher("apres la declaration et l'initialisation", rect);
Afficher(rect, "apres la declaration et l'initialisation");
Console.WriteLine("Fin de la deuxieme demonstration :\n\n");
}
static void Main(string[] args) {
// Demo1();
Demo2();
} }
/* Execution:
--- Deuxieme demonstration : ---
On appelle le constructeur a deux parametres de Rectangle On appelle le constructeur a deux parametres de Rectangle On appelle le constructeur a deux parametres de Rectangle On appelle le constructeur a un parametre de Rectangle On appelle le constructeur a deux parametres de Rectangle On appelle le constructeur de RectangleVisible
On appelle le constructeur a deux parametres de Rectangle On appelle le constructeur de RectangleColore
On appelle le constructeur a deux parametres de Rectangle On appelle le constructeur a un parametre de Rectangle On appelle le constructeur de Carre
Infos du tableau des rectangles rect apres la declaration et l'initialisation:
On appelle le ToString() de Rectangle 0) 10,20 6,40 65,280
On appelle le ToString() de Rectangle 1) 5,00 4,00 20,000
On appelle le ToString() de Rectangle 2) 7,20 7,20 51,840
On appelle le ToString() de Rectangle
3) En tant que rectangle : 10,20 6,40 65,280 ESt-il visible? - True
On appelle le ToString() de Rectangle
4) En tant que rectangle : 7,80 4,20 32,760 ESt-il colore ? - False
On appelle le ToString() de Rectangle
5) En tant que rectangle : 8,30 8,30 68,890 Comme carre : diagonale = 11,7379725676967
Infos du tableau des rectangles rect apres la declaration et l'initialisation:
0) Rectangle : < 10,20, 6,40, 65,28>
1) Rectangle : < 5,00, 4,00, 20,00>
2) Rectangle : < 7,20, 7,20, 51,84>
3) Rectangle visible : < 10,20, 6,40, 65,28, True>
4) Rectangle colore : < 7,80, 4,20, 32,76, 24,00, False>
5) Carre : < 8,30, 8,30, 68,89, 11,74>
La surface totale : 304,05
Fin de la deuxieme demonstration :
Press any key to continue
*/