mercredi 20 août 2014

cour vb 2008 heritage




-->












Polymorphisme et surcharge




















1.
La Surcharge





La
surcharge est une technique simple à utiliser, qui permet d'utiliser le même nom
de fonction avec des paramètres de différents types. Voyons ce que ça donne sur
la classe Addition dans l'exemple qui suit.



Comme d'habitude, nous avons besoin de l'espace de noms
System :














Imports System

Class Addition







Ensuite, ajoutons 2 fonctions Add(). La
première additionne 2 entiers ... (Convert.ToString est l'équivalent de la
fonction CStr de VB6)














    Overloads Public Sub Add(A as Integer, B as Integer)

        Console.Writeline ("Adding Integers: " + Convert.ToString(a + b))

    End Sub






... et
la deuxième concatène 2 chaînes de caractères :














    Overloads Public Sub Add(A as String, B as String)

        Console.Writeline ("Adding Strings: " + a + b)

    End Sub






Et les
2 ont le même noms ? Ceci est possible uniquement car nous avons utilisé le
mot-clé Overloads dans leur déclaration, pour
justement spécifier la surcharge !



Ici, voyons ce que ça donne avec la procédure Main()
suivante, incluse dans le module de classe Addition
(et donc déclarée en tant que partagée, cf paragraphe précédent) :


















    Shared Sub Main()

        Dim monCalcul as Addition

        'Créée l'objet

        monCalcul = New Addition

        

        'Appel de la première fonction ...

        monCalcul.Add(10, 20)

        

        ' ... et appel de la seconde :

        monCalcul.Add("Bonjour", " comment allez-vous ?")

    End Sub

End Class

 

 

 

 












Signature :




C'est ainsi que l'on appelle chaque séquence distincte de paramètres,
c'est-à-dire chaque manière de faire appel à la méthode surchargée.





2.
L'Héritage




L'héritage est un mécanisme par lequel une classe dérivée (ou classe fille)
hérite de toutes les caractéristiques de sa classe de base (ou classe mère). En
bref, il est possible de créer via héritage vos classes à partir d'une classe
existante : Il suffit pour cela d'utiliser le mot-clé
Inherits
.



Voici un exemple simple. Commençons par importer l'espace de noms habituel :














Imports System






Voici
notre classe de base :














Class Humain

    'Quelque chose que la plupart des êtres humains font :

    Public Sub Marche()

        Console.Writeline ("Je marche ...")

    End Sub

End Class






Et
maintenant, créons une classe fille nommée Developpeur
:














Class Developpeur

    Inherits Humain

    'Nous avons donc déjà accès à la méthode Marche() définie ci-dessus

    'Et voici une autre qui illustre ce que certains programmeurs font parfois :

    Public Sub PiqueDuCode()

        Console.Writeline ("Je pompe du code ...")

    End Sub

End Class






Ce qui
nous permet de coder la procédure MainClass()
suivante :














Class MainClass

    'Notre procédure principale :

    Shared Sub Main()

        Dim Tom as Developpeur

        Tom = New Developpeur

        

        'Cet appel est valide puisque Developpeur a accès à cette fonction 

        'héritée de la classe Humain :

        Tom.Marche()

        

        'Celui-ci également puisque Tom est une instance de la classe Developpeur

        Tom.PiqueDuCode()

    End Sub

End Class















Compléments :




MustInherit




Ce mot clé indique qu'une classe ne peut être instanciée, et qu'elle ne peut
donc être utilisée que comme classe de base. Par exemple, si vous
déclarez la classe Humain en tant que "MustInherit
Humain", alors vous ne pourrez pas créer
d'objets de type Humain à partir de cette classe, mais seulement à partir de
classes dérivées.



NotInheritable




A l'inverse, ce mot-clé indique que cette classe ne peut pas être héritée,
c'est-à-dire servir de classe de base. Par exemple, si vous déclarez la classe
Humain en tant que "NotInheritable
Humain", aucune classe dérivée ne pourra lui
être créée.


3.
La Rédéfinition



Par
défaut, une classe dérivée hérite des méthodes de sa classe de base. Mais si une
propriété ou une méthode doit avoir un comportement différent dans la classe
fille, elle doit y être redéfinie !



En fait, il suffit de définir une nouvelle implémentation de la méthode dans la
classe dérivée :

Le mot-clé Overridable est utilisé pour préciser
qu'une méthode peut être redéfinie,

et le mot-clé Overrides est quant à lui utilisé
pour indiquer quelles méthodes sont redéfinies.



Étudions ceci sur un exemple, à partir de notre classe
Humain
:














Imports System

Class Humain

    'Parle() est redéfinissable :

    Overridable Public Sub Parle()

        Console.Writeline ("Je parle")

    End Sub

End Class







Maintenant, créons une classe dérivée de Humain
:

















Un
Indien (Indien) est un humain (Humain)
:














Class Indien

    Inherits Humain

    'Notre Indien parle l'Hindi, la langue nationale en Inde

    'la méthode Parle() qui suit redéfinit la méthode Parle() de la classe de base (Humain)

    Overrides Public Sub Parle()

        Console.Writeline ("Je parle Hindou")

    End Sub

End Class







Important : Évidemment, un appel de Parle()
à partir d'un objet d'une classe dérivée va faire appel à la méthode Parle() de
cette même classe.

Si vous souhaitez faire référence à la méthode Parle() de la classe de

base, il vous suffit alors d'utiliser le mot-clé
MyBase, comme ceci :














Mybase.Parle()






Voici
une classe pour tester nos exemples :














Class MainClass

    'Notre procédure principale :

    Shared Sub Main()

        'Tom est un humain

        Dim Tom as Humain

        Tom = New Humain

        

        'Tony est humain, et plus précisement Indien

        Dim Tony as Indien

        Tony = New Indien

        

        'Voici un appel à la méthode Parle() de la classe Humain :

        Tom.Parle()

        

        'Et un appel de la méthode Parle() de la classe Indien

        Tony.Parle()

    End Sub

End Class














4.
Le Polymorphisme d'héritage




Le polymorphisme est un mécanisme via
lequel un objet peut prendre plus d'une forme. Par exemple, si vous avez une
classe de base nommée Humain, un objet de type Humain peut être utilisé pour
contenir un objet de n'importe laquelle de ses classes dérivées. Quand vous
appelez une méthode à partir de votre objet, le système déterminera
automatiquement le type de l'objet afin d'appeler la fonction appropriée.



Imaginons par exemple une méthode nommée Parle() dans la classe de base Humain.
Créons ensuite une classe fille et redéfinissons-y la méthode Parle(). Puis
créez un objet de la classe fille et affectez-lui la variable de la classe mère
: maintenant, si vous faites appel à la méthode Parle() à partir de cette
variable, ce sera celle définie dans votre classe fille qui sera appelée.



Au contraire, si vous affectez à cette variable un objet de la classe mère,
alors ce sera la méthode Parle() de la classe mère qui sera appelée.



Ceci est déterminé lors de la compilation, c'est ce qu'on appelle une liaison
tardive.



Reprenons l'exemple du paragraphe précédent : la différence se situe dans la
procédure Shared Sub Main(), de la classe MainClass. Étudions le code pour voir
ce qui a changé :















Import Systems

 

Class Humain

    'Parle() peut être redéfinie :

    Overridable Public Sub Parle()

        Console.Writeline ("Je parle")

    End Sub

End Class







Maintenant, créons une classe dérivée de
Humain :



Un Indien (Indien) est un humain (Humain) :














Class Indien

    Inherits Humain

    

    'Notre Indien parle l'Hindi, la langue nationale en Inde

    'la méthode Parle() qui suit redéfinit la méthode Parle() de la classe de base (Humain)

    Overrides Public Sub Parle()

        Console.Writeline ("Je parle Hindou")

    End Sub

End Class







Étudions soigneusement le code suivant :














Class MainClass

    'Notre fonction principale :

    Shared Sub Main()

        'Tom est un humain (classe de base)

        Dim Tom as Humain

        

        'Affectons-lui une variable de la classe fille Indien

        Tom = New Indian

        'Cette affectation est correcte, car la classe Indien

        'est fille de la classe Humain.

        

        'Puis faisons appel à la méthode Parle comme ceci :

        Tom.Parle()

    End Sub

End Class

 




Sur le
dernier appel (Tom.Parle()), quelle procédure va être exécutée ?




Celle
de la classe Indien, ou bien celle de la classe Humain ?

Cette question est pertinente, car Tom a été déclaré en tant qu'Humain, mais un
objet de type Indien lui a été affecté.



La réponse est : c'est la méthode Parle() de la classe Indien va être appelée.

Ceci parce que, comme la plupart des langages orientés objet, Vb.NET peut
automatiquement détecter le type de l'objet assigné à la variable appartenant à
la classe de base : c'est ce que l'on appelle le Polymorphisme.










5.
Constructeurs
et Destructeurs




Un constructeur (Constructor) est une
procédure spéciale qui est automatiquement exécutée quand un objet est créé. Une
telle procédure se nomme New(). Comme indiqué dans la leçon 4, les constructeurs
peuvent faire l'objet de surcharge mais contrairement aux autres méthodes, le
mot clé Overloads n'est pas requis.



Par opposition, un destructeur (Destructor) est une procédure qui est
automatiquement exécutée à la mort de l'objet. Une telle procédure se nomme
Finalize(). En VB6, ces procédures étaient déjà disponibles, elles se nommaient
Class_Initialize() et Class_Terminate().




Démarrons l'étude d'un exemple, avec la classe Chien
:














Imports System

 

Class Chien

    'La variable age

    Private Age as integer






Voici
un constructeur :














    Public Sub New()

        Console.Writeline ("Un chien est né")

        Age = 0

    End Sub










Et
grâce à la surcharge, un 2° exemple de constructeur (avec paramètre cette
fois-ci) :














    Public Sub New(val as Integer)

        Console.Writeline ("Nouveau chien dont l'âge est " + Convert.ToString(val))

        Age = val

    End Sub






Voici
le code du destructeur, suivi de la procédure habituelle
Main() :














    Overrides Protected Sub Finalize()

        Console.Writeline ("Paf le chien ... (désolé)")

    End Sub

    

    'La fonction principale :

    Shared Sub Main()

        Dim Jimmy, Jacky as Chien

        

        'Création des objets 

        'Ceci va appeler le contructeur n°1

        Jimmy = New Chien

        

        'Et ceci le contructeur n°2

        Jacky = New Chien (10)

    End Sub

    

End Class






La
destruction intervient automatiquement en fin de portée ou de programme, grâce
au Garbage Collector. Il est possible de faire le ménage vous-même en détruisant
vos objets.

Ex :














Jimmy = Nothing





Les Propriétés




Pour
gérer les données de vos objets, vous avez le choix entre des champs ou des
propriétés. Mais alors que les champs sont de simples variables publiques, les
propriétés utilisent des procédures pour encadrer la lecture et la mise à jour
des données (cf. la définition d'encapsulation). Ce sont les mots-clé
Get (lecture) et Set
(mise à jour) qui sont utilisées pour la déclaration de ces procédures.



Étudions l'exemple suivant :














Imports System

 

Public Class Chien

    'Utilisons une variale privée pour l'âge :

    Private mAgeDuChien as Integer








Et
voici nos procédures Property :














    Public Property Age() As Integer

    'Lecture de l'âge :

    Get

        Console.Writeline ("Getting Property")

        Return mAgeDuChien

    End Get

 

    'MAJ de l'âge :

    Set(ByVal Value As Integer)

        Console.Writeline ("Setting Property")

        mAgeDuChien = Value

    End Set

 

    End Property

End Class






Voyons
comment utiliser ces procédures :














Class MainClass

    'Début du programme :

    Shared Sub Main()

    

    'Créons un objet :

    Dim Jimmy as Chien

    Jimmy = New Chien      

      

    'Nous ne pouvons accéder directement à la variable mAgeDuChien,

    'nous devons utiliser la procédure Age().

    'Affectons-lui une valeur. La procédure Set Age sera mise à contribution :

    Jimmy.Age = 30

    

    'Récupérons maintenant cette valeur : c'est au tour de la procédure Get Age de travailler :

    Dim curAge = Jimmy.Age()

    

    End Sub

End Class
















Documentation Visual Studio. Net















Polymorphisme et surcharge




























1.
La Surcharge





La
surcharge est une technique simple à utiliser, qui permet d'utiliser le même nom
de fonction avec des paramètres de différents types. Voyons ce que ça donne sur
la classe Addition dans l'exemple qui suit.



Comme d'habitude, nous avons besoin de l'espace de noms
System :














Imports System

Class Addition







Ensuite, ajoutons 2 fonctions Add(). La
première additionne 2 entiers ... (Convert.ToString est l'équivalent de la
fonction CStr de VB6)














    Overloads Public Sub Add(A as Integer, B as Integer)

        Console.Writeline ("Adding Integers: " + Convert.ToString(a + b))

    End Sub






... et
la deuxième concatène 2 chaînes de caractères :














    Overloads Public Sub Add(A as String, B as String)

        Console.Writeline ("Adding Strings: " + a + b)

    End Sub






Et les
2 ont le même noms ? Ceci est possible uniquement car nous avons utilisé le
mot-clé Overloads dans leur déclaration, pour
justement spécifier la surcharge !



Ici, voyons ce que ça donne avec la procédure Main()
suivante, incluse dans le module de classe Addition
(et donc déclarée en tant que partagée, cf paragraphe précédent) :


















    Shared Sub Main()

        Dim monCalcul as Addition

        'Créée l'objet

        monCalcul = New Addition

        

        'Appel de la première fonction ...

        monCalcul.Add(10, 20)

        

        ' ... et appel de la seconde :

        monCalcul.Add("Bonjour", " comment allez-vous ?")

    End Sub

End Class

 

 

 

 












Signature :




C'est ainsi que l'on appelle chaque séquence distincte de paramètres,
c'est-à-dire chaque manière de faire appel à la méthode surchargée.





2.
L'Héritage




L'héritage est un mécanisme par lequel une classe dérivée (ou classe fille)
hérite de toutes les caractéristiques de sa classe de base (ou classe mère). En
bref, il est possible de créer via héritage vos classes à partir d'une classe
existante : Il suffit pour cela d'utiliser le mot-clé
Inherits
.



Voici un exemple simple. Commençons par importer l'espace de noms habituel :














Imports System






Voici
notre classe de base :














Class Humain

    'Quelque chose que la plupart des êtres humains font :

    Public Sub Marche()

        Console.Writeline ("Je marche ...")

    End Sub

End Class






Et
maintenant, créons une classe fille nommée Developpeur
:














Class Developpeur

    Inherits Humain

    'Nous avons donc déjà accès à la méthode Marche() définie ci-dessus

    'Et voici une autre qui illustre ce que certains programmeurs font parfois :

    Public Sub PiqueDuCode()

        Console.Writeline ("Je pompe du code ...")

    End Sub

End Class






Ce qui
nous permet de coder la procédure MainClass()
suivante :














Class MainClass

    'Notre procédure principale :

    Shared Sub Main()

        Dim Tom as Developpeur

        Tom = New Developpeur

        

        'Cet appel est valide puisque Developpeur a accès à cette fonction 

        'héritée de la classe Humain :

        Tom.Marche()

        

        'Celui-ci également puisque Tom est une instance de la classe Developpeur

        Tom.PiqueDuCode()

    End Sub

End Class















Compléments :




MustInherit




Ce mot clé indique qu'une classe ne peut être instanciée, et qu'elle ne peut
donc être utilisée que comme classe de base. Par exemple, si vous
déclarez la classe Humain en tant que "MustInherit
Humain", alors vous ne pourrez pas créer
d'objets de type Humain à partir de cette classe, mais seulement à partir de
classes dérivées.



NotInheritable




A l'inverse, ce mot-clé indique que cette classe ne peut pas être héritée,
c'est-à-dire servir de classe de base. Par exemple, si vous déclarez la classe
Humain en tant que "NotInheritable
Humain", aucune classe dérivée ne pourra lui
être créée.


3.
La Rédéfinition



Par
défaut, une classe dérivée hérite des méthodes de sa classe de base. Mais si une
propriété ou une méthode doit avoir un comportement différent dans la classe
fille, elle doit y être redéfinie !



En fait, il suffit de définir une nouvelle implémentation de la méthode dans la
classe dérivée :

Le mot-clé Overridable est utilisé pour préciser
qu'une méthode peut être redéfinie,

et le mot-clé Overrides est quant à lui utilisé
pour indiquer quelles méthodes sont redéfinies.



Étudions ceci sur un exemple, à partir de notre classe
Humain
:














Imports System

Class Humain

    'Parle() est redéfinissable :

    Overridable Public Sub Parle()

        Console.Writeline ("Je parle")

    End Sub

End Class







Maintenant, créons une classe dérivée de Humain
:

















Un
Indien (Indien) est un humain (Humain)
:














Class Indien

    Inherits Humain

    'Notre Indien parle l'Hindi, la langue nationale en Inde

    'la méthode Parle() qui suit redéfinit la méthode Parle() de la classe de base (Humain)

    Overrides Public Sub Parle()

        Console.Writeline ("Je parle Hindou")

    End Sub

End Class







Important : Évidemment, un appel de Parle()
à partir d'un objet d'une classe dérivée va faire appel à la méthode Parle() de
cette même classe.

Si vous souhaitez faire référence à la méthode Parle() de la classe de

base, il vous suffit alors d'utiliser le mot-clé
MyBase, comme ceci :














Mybase.Parle()






Voici
une classe pour tester nos exemples :














Class MainClass

    'Notre procédure principale :

    Shared Sub Main()

        'Tom est un humain

        Dim Tom as Humain

        Tom = New Humain

        

        'Tony est humain, et plus précisement Indien

        Dim Tony as Indien

        Tony = New Indien

        

        'Voici un appel à la méthode Parle() de la classe Humain :

        Tom.Parle()

        

        'Et un appel de la méthode Parle() de la classe Indien

        Tony.Parle()

    End Sub

End Class














4.
Le Polymorphisme d'héritage




Le polymorphisme est un mécanisme via
lequel un objet peut prendre plus d'une forme. Par exemple, si vous avez une
classe de base nommée Humain, un objet de type Humain peut être utilisé pour
contenir un objet de n'importe laquelle de ses classes dérivées. Quand vous
appelez une méthode à partir de votre objet, le système déterminera
automatiquement le type de l'objet afin d'appeler la fonction appropriée.



Imaginons par exemple une méthode nommée Parle() dans la classe de base Humain.
Créons ensuite une classe fille et redéfinissons-y la méthode Parle(). Puis
créez un objet de la classe fille et affectez-lui la variable de la classe mère
: maintenant, si vous faites appel à la méthode Parle() à partir de cette
variable, ce sera celle définie dans votre classe fille qui sera appelée.



Au contraire, si vous affectez à cette variable un objet de la classe mère,
alors ce sera la méthode Parle() de la classe mère qui sera appelée.



Ceci est déterminé lors de la compilation, c'est ce qu'on appelle une liaison
tardive.



Reprenons l'exemple du paragraphe précédent : la différence se situe dans la
procédure Shared Sub Main(), de la classe MainClass. Étudions le code pour voir
ce qui a changé :















Import Systems

 

Class Humain

    'Parle() peut être redéfinie :

    Overridable Public Sub Parle()

        Console.Writeline ("Je parle")

    End Sub

End Class







Maintenant, créons une classe dérivée de
Humain :



Un Indien (Indien) est un humain (Humain) :














Class Indien

    Inherits Humain

    

    'Notre Indien parle l'Hindi, la langue nationale en Inde

    'la méthode Parle() qui suit redéfinit la méthode Parle() de la classe de base (Humain)

    Overrides Public Sub Parle()

        Console.Writeline ("Je parle Hindou")

    End Sub

End Class







Étudions soigneusement le code suivant :














Class MainClass

    'Notre fonction principale :

    Shared Sub Main()

        'Tom est un humain (classe de base)

        Dim Tom as Humain

        

        'Affectons-lui une variable de la classe fille Indien

        Tom = New Indian

        'Cette affectation est correcte, car la classe Indien

        'est fille de la classe Humain.

        

        'Puis faisons appel à la méthode Parle comme ceci :

        Tom.Parle()

    End Sub

End Class

 




Sur le
dernier appel (Tom.Parle()), quelle procédure va être exécutée ?




Celle
de la classe Indien, ou bien celle de la classe Humain ?

Cette question est pertinente, car Tom a été déclaré en tant qu'Humain, mais un
objet de type Indien lui a été affecté.



La réponse est : c'est la méthode Parle() de la classe Indien va être appelée.

Ceci parce que, comme la plupart des langages orientés objet, Vb.NET peut
automatiquement détecter le type de l'objet assigné à la variable appartenant à
la classe de base : c'est ce que l'on appelle le Polymorphisme.










5.
Constructeurs
et Destructeurs




Un constructeur (Constructor) est une
procédure spéciale qui est automatiquement exécutée quand un objet est créé. Une
telle procédure se nomme New(). Comme indiqué dans la leçon 4, les constructeurs
peuvent faire l'objet de surcharge mais contrairement aux autres méthodes, le
mot clé Overloads n'est pas requis.



Par opposition, un destructeur (Destructor) est une procédure qui est
automatiquement exécutée à la mort de l'objet. Une telle procédure se nomme
Finalize(). En VB6, ces procédures étaient déjà disponibles, elles se nommaient
Class_Initialize() et Class_Terminate().




Démarrons l'étude d'un exemple, avec la classe Chien
:














Imports System

 

Class Chien

    'La variable age

    Private Age as integer






Voici
un constructeur :














    Public Sub New()

        Console.Writeline ("Un chien est né")

        Age = 0

    End Sub










Et
grâce à la surcharge, un 2° exemple de constructeur (avec paramètre cette
fois-ci) :














    Public Sub New(val as Integer)

        Console.Writeline ("Nouveau chien dont l'âge est " + Convert.ToString(val))

        Age = val

    End Sub






Voici
le code du destructeur, suivi de la procédure habituelle
Main() :














    Overrides Protected Sub Finalize()

        Console.Writeline ("Paf le chien ... (désolé)")

    End Sub

    

    'La fonction principale :

    Shared Sub Main()

        Dim Jimmy, Jacky as Chien

        

        'Création des objets 

        'Ceci va appeler le contructeur n°1

        Jimmy = New Chien

        

        'Et ceci le contructeur n°2

        Jacky = New Chien (10)

    End Sub

    

End Class






La
destruction intervient automatiquement en fin de portée ou de programme, grâce
au Garbage Collector. Il est possible de faire le ménage vous-même en détruisant
vos objets.

Ex :














Jimmy = Nothing





Les Propriétés




Pour
gérer les données de vos objets, vous avez le choix entre des champs ou des
propriétés. Mais alors que les champs sont de simples variables publiques, les
propriétés utilisent des procédures pour encadrer la lecture et la mise à jour
des données (cf. la définition d'encapsulation). Ce sont les mots-clé
Get (lecture) et Set
(mise à jour) qui sont utilisées pour la déclaration de ces procédures.



Étudions l'exemple suivant :














Imports System

 

Public Class Chien

    'Utilisons une variale privée pour l'âge :

    Private mAgeDuChien as Integer








Et
voici nos procédures Property :














    Public Property Age() As Integer

    'Lecture de l'âge :

    Get

        Console.Writeline ("Getting Property")

        Return mAgeDuChien

    End Get

 

    'MAJ de l'âge :

    Set(ByVal Value As Integer)

        Console.Writeline ("Setting Property")

        mAgeDuChien = Value

    End Set

 

    End Property

End Class






Voyons
comment utiliser ces procédures :














Class MainClass

    'Début du programme :

    Shared Sub Main()

    

    'Créons un objet :

    Dim Jimmy as Chien

    Jimmy = New Chien      

      

    'Nous ne pouvons accéder directement à la variable mAgeDuChien,

    'nous devons utiliser la procédure Age().

    'Affectons-lui une valeur. La procédure Set Age sera mise à contribution :

    Jimmy.Age = 30

    

    'Récupérons maintenant cette valeur : c'est au tour de la procédure Get Age de travailler :

    Dim curAge = Jimmy.Age()

    

    End Sub

End Class
















Documentation Visual Studio. Net