Accueil
Club Emploi Blogs   TV   Dév. Web PHP XML Python Autres 2D-3D-Jeux Sécurité Windows Linux PC Mac
Accueil Conception Java DotNET Visual Basic  C  C++ Delphi Eclipse MS-Office SQL & SGBD Oracle  4D  Business Intelligence

Cours VB.NET

Date de mise à jour : 05/12/2010


XV-G. Composition et groupe d'objets : Tableau, collection d'objets, Classe contenant un groupe d'objets
XV-G-1. Un Objet dans un autre : Composition d'objets
XV-G-2. Groupe d'objets
XV-G-2-a. Comment utiliser un tableau ou une collection d'objets 'Salarié'
XV-G-2-b. Utiliser Une Classe contenant des Salariés
XV-G-2-b-i. Créer une Classe contenant une ArrayList
XV-G-2-b-ii. Créer une Classe héritant de la Classe ArrayList
XV-G-2-b-iii. Créer une Classe héritant de la Classe CollectionBase
XV-G-2-b-iv. Créer une Classe contenant une Classe générique
XV-G-2-b-v. Conclusion
XV-H. Conservation (sauvegarde) d'objet, sérialisation
XV-H-1. La Sérialisation
XV-H-2. Exemple 1 : Sérialisation binaire
XV-H-3. Sérialisation
XV-H-4. Déserialisation
XV-H-5. Exemple 2 : Sérialisation XML
XV-H-6. Exemple 3 : Sérialisation d'une collection
XV-H-7. Exemple 4 : Sérialisation d'un tableau
XV-H-8. Exemple 5 : Sérialisation d'une collection générique
XV-I. Surcharge
XV-I-1. Surcharge en VB 2003
XV-I-2. Surcharge en VB 2005 : nouveautés


XV-G. Composition et groupe d'objets : Tableau, collection d'objets, Classe contenant un groupe d'objets

Est-il possible de mettre un objet dans un autre?

On a souvent besoin d'utiliser un ensemble, un groupe d'objets. Comment faire?


XV-G-1. Un Objet dans un autre : Composition d'objets

On parle de contenant-contenu.

On peut créer une Classe qui contient des Objets, une classe qui se compose d'objets.


Exemple classique:

Créons une Classe Point.

Class Point
Private _x As Integer
Private _y As Integer
Public Sub New(ByVal x As Integer, y As Integer)
          _x=x
          _y=y
End Sub 
...
End Class
On a écrit uniquement le constructeur, il faudrait aussi écrire les property permettant de lire et écrire les coordonnées du point.


Maintenant on a besoin de créer une Classe rectangle qui est définie par 2 points (le coin supérieur gauche et le coin inférieur droit):

Class Rectangle
Private _p1 As Point
Private _p2 As Point 
Public Sub New(ByVal x1 As Integer, ByVal y1 As Integer,ByVal x2 As Integer, ByVal y2 As Integer)
          _p1= New Point (x1,y1)
          _p2= New Point (x2,y2)
End Sub 
...
End Class
 

Et bien, on utilise la classe Point dans la Classe Rectangle. le constructeur de la classe rectangle instancie 2 points, ce qui appelle le constructeur de la Classe Point.


XV-G-2. Groupe d'objets

Exemple: créons une Classe 'Salarié' avec une Property Nom et un constructeur New nécessitant un nom.

Public Class Salarié
Private _sNom As String
Public Property Nom() As String
          Get
               Nom = _sNom 
          End Get
          Set 
               _sNom = Value
          End Set
     End Property

Public Sub New(ByVal sNom As String)
          Nom = sNom 
End Sub 
 
End Class
 

Ensuite pour travailler sur un ensemble de salariés on peut:

  • Utiliser un tableau ou une collection de Salariés (pas bien !!)
  • Créer une Classe contenant des Salariés (good!)

XV-G-2-a. Comment utiliser un tableau ou une collection d'objets 'Salarié'

Voyons comment faire avec une approche non objet:
  • Tableau
    
    Dim LesSalaries(100)  As  Salarié
    
    Attention, cela crée un tableau de références d'objet, mais pas les objets (Salariées(1) contient Nothing).

    Il faut donc créer les objets:
    
    LesSalaries(0) = New Salarié("toto")
    LesSalaries(1) = New Salarié("lulu")
    LesSalaries(2) = New Salarié("tata")
    ..
     
    
    On peut ensuite utiliser LesSalaries(1).Nom pour connaître le nom du salarié d'index 1.

  • Collection
    
    Dim LesSalaries As New ArrayList  'On crée une collection d'objet ArrayList
    Dim s As New Salarié("toto")      'On crée un Salarié
    LesSalaries.Add (s)               'On l'ajoute dans l'Arraylist
     
    LesSalariées.Count   retourne 1
     
    

    Pour afficher dans une MsgBox le nom du Salarié d'index 1:
    
    MsgBox(CType(LesSalaries.Item(0), Salarié).Nom) 
    
    On remarque que LesSalaries.Item(0) est de type Objet (Les éléments d'un ArrayList sont des objets; Salaries.Item(0).GetType.BaseType.ToString retourne 'Objet') il faut donc caster en 'Salarié' à l'aide de CType:

    CType(LesSalaries.Item(0), Salarié) ensuite , on peut utiliser .Nom

    En Vb2005 (Framework 2):

    On peut utiliser des collections 'génériques'
    
    Dim LesSalaries As New System.Collections.Generic.List(Of Salarié)
    
    On peut ainsi créer une collection fortement typée de 'Salarié'.

    Mais utiliser un tableau ou une collection d'objets directement accessibles n'est pas une bonne méthode.

    La bonne méthode est de créer une classe qui encapsule la collection (Une Classe qui contient la collection). Voyons donc la suite.


XV-G-2-b. Utiliser Une Classe contenant des Salariés

Voyons comment faire avec une approche objet:


Il faut créer une classe 'LesSalariés' contenant:
  • un tableau ou une collection 'Private' complètement encapsulé, donc non accessible à l'extérieur.
  • les méthodes 'Public' permettant d'avoir accès au données et de les modifier.

Il y a 4 manières de faire:


XV-G-2-b-i. Créer une Classe contenant une ArrayList
Voyons un exemple utilisant une ArrayList (collection d'objets):

L'arrayList est créée par le constructeur.

Noter l'encapsulation:
  • une méthode Add permet d'ajouter un 'Salarié' aux 'Salariés' (vu du coté utilisateur).
  • La méthode Remove permet d'enlever un Salarié.
  • Dans la classe une méthode Add permet d'ajouter un 'Salarié' à l'ArrayList.
  • La Property Item permet de retourner un Salarié d'index lIndex.
  • La Property Count retourne le nombre de Salarié.
 
Imports System.Collections
Public Class LesSalariésClasse
     Private maCol As ArrayList

     Public Sub New()
          maCol = New ArrayList()    'cela crée une ArrayList
     End Sub

     Public Function GetEnumerator() As IEnumerator    'permet d'utiliser For Each
          GetEnumerator = maCol.GetEnumerator
     End Function 

     Public Function Add(ByVal LeNom As String) As Salarié
          Dim UnSalarié As New Salarié(LeNom)
          maCol.Add(UnSalarié)
          Add = UnSalarié 
     End Function

      Public ReadOnly Property Item(ByVal lIndex As Integer) As Salarié
          Get 
               Item = (CType(maCol.Item(lIndex),Salarié)
          End Get
     End Property

      Public ReadOnly Property Count() As Integer
          Get 
               Count = maCol.Count 
          End Get
     End Property

      Public Sub Remove(ByVal Key As String)
          maCol.Remove(Key) 
     End Sub
End Class

Pour utiliser la Classe:

Dim LesSalariés As New LesSalariésClasse() 'création 
LesSalariés.Add("Philippe")    'Ajout d'un salarié
LesSalariés.Count retourne 1   'connaître le nombre de salariés
Pour afficher le nom du premier salarié dans une MessageBox:
MsgBox(LesSalariés.Item(0).Nom)

Bien sur on peut utiliser une boucle For Each pour avoir accès à l'ensemble des salariés.


XV-G-2-b-ii. Créer une Classe héritant de la Classe ArrayList
On crée une classe héritant de ArrayList, ensuite on va créer une méthode Add pour ajouter un Salarié et une Property permettant de lire le nom du salarié d'index i; comme il existe déjà les membres Add et Index avec la même signature dans la classe parente, il faut remplacer ces membres, on le fait grâce à 'Shadows'.

Dans les nouveaux membres, on appelle les membres de la classe mère (grâce à MyBase)

Imports System.Collections
Public Class Salariés
     Inherits ArrayList

    
     Public  Shadows Sub Add(ByVal S As Salarié) 
          MyBase.Add(S) 
     End Function

      Public Shadows ReadOnly Property Index(ByVal i As Integer) As Salarié
          Get 
               Return CType (MyBase.Item(i), Salarié)
          End Get
     End Property

      
End Clas
Là aussi, les éléments d'un ArrayList sont des objets; il faut donc caster en 'Salarié' à l'aide de CType l'Item de l'ArrayList:


Dans l'exemple, on a utilisé une ArrayList, il est possible d'utiliser tout autre type de collections.


XV-G-2-b-iii. Créer une Classe héritant de la Classe CollectionBase
CollectionBase est une classe abstraite (ne pouvant pas être utilisée telle quelle), on peut créer une classe qui en hérite.

Cela tombe bien: CollectionBase contient déjà quelques fonctions propres aux collections (Clear et Count), les fonctions qui manquent, qui n'existent pas (Add, Remove, Item) vont être implémentées par vous et à votre manière.

Une propriété Protected appelée List est fournit par CollectionBase et utilisée pour le stockage et l'organisation interne. Quand on crée Add, Remove, Item, on utilise cette propriété List.


Public Class MaCollection
Inherits System.Collections.CollectionBase
Public Sub Add(ByVal a As Salarié)
' Appelle la méthode Add de l'objet List pour ajouter un salarié.
List.Add(a)
End Sub

End Class

Remarquons que, bien que l'objet List soit non typé, cette méthode interdit l'ajout de tous les objets n'appartenant pas aux type Salarié. Alors que CollectionBase n'était pas typée, MaCollection est fortement typée car n'acceptant que des 'Salarié'.

On peut aussi ajouter une méthode éliminant un objet de la collection:

Public Sub Remove(ByVal index as Integer)
' contrôle.
If index > Count - 1 Or index < 0 Then
    System.Windows.Forms.MessageBox.Show("Index non  valide!")
Else
' Appelle la méthode RemoveAt de l'objet List.
List.RemoveAt(index)
End If
End Sub

On peut enfin ajouter Item:

Public ReadOnly Property Item(ByVal index as Integer) As Salarié
Get
Return CType(List.Item(index), Salarié)
End Get
End Property

Avec le Framework 2, il est possible d'utiliser, au lieu de ListArray, une collection générique fortement typée:

System.Collections.Generic.List(Of Salarié)  

XV-G-2-b-iv. Créer une Classe contenant une Classe générique
C'est possible avec le Framework 2

Au lieu de créer une ArrayList dans la Classe, on peut créer une collection générique (System.Collections.Generic) et lui imposer un type.

Ici on va créer une collection de salariés.

Imports System.Collections
Public Class LesSalariésClasse
     Private maCol As System.Collections.Generic.List(Of Salarié)

     Public Sub New()
          maCol = New System.Collections.Generic.List(Of Salarié)    'cela crée une Collection de salarié
     End Sub

     
     Public Function Add(ByVal Sal As Salarié)
          maCol.Add(Sal)
          Add = Sal 
     End Function
     Public ReadOnly Property Item(ByVal lIndex As Integer) As Salarié
          Get 
               Item = maCol.Item(lIndex)  'On a directement un Objet Salarié: pas besoin de CType
          End Get
     End Property
...
End Class

On peut aussi créer des Stack(Of..) Queue(Of..), Dictionnary(Of..) SortedList(Of..) ..


Cette méthode utilisant une collection d'objets complètement encapsulés est une bonne méthode.


XV-G-2-b-v. Conclusion
Si une classe doit contenir des objets:
  • Si la classe à besoin d'utiliser et d'exposer un petit nombre d'objets, implémentez chaque objet en tant que propriété.
  • Si le nombre d'objets contenus est grand (et que ce nombre n'est pas connu ou pas fixe) implémentez une propriété de collection.
Si vous ne voulez pas que des applications clientes puissent utiliser les objets contenus, définissez ces objets comme Friend ou Private.


XV-H. Conservation (sauvegarde) d'objet, sérialisation

Quand un objet est détruit (fin de programme), les valeurs de ses attributs (les variables) sont perdues!!

Si les valeurs de l'objet changent et doivent être retrouvées lors d'une utilisation ultérieure du programme, il faut les enregistrer.

On pourrait enregistrer chaque attribut dans un fichier séquentiel (FileOpen puis Print..).

On peut aussi utiliser la sérialisation.


XV-H-1. La Sérialisation

La sérialisation est le processus de conversion d'un objet ou d'un groupe d'objets en séquence linéaire d'octets pour stockage ou transmission à un autre emplacement. La désérialisation est le processus consistant à accepter des informations stockées et à recréer des objets à partir de celles-ci.

La sérialisation consiste donc à stocker les valeurs des attributs d'une instance d'un objet dans un fichier qui peut être au format binaire, xml ou Soap.
  • La sérialisation binaire concerne les champs publics et privés de l'objet et le nom de la classe, y compris l'assembly contenant la classe.
  • La sérialisation XML ne sérialise que les champs publics et les valeurs des propriétés d'un objet (si elles ne sont pas en lecture seule) dans un flux XML. La sérialisation n'inclut pas d'informations de type.
Lors de la sérialisation, les champs et propriétés sont convertis en un flux d'octets, qui est alors écrit dans un flux de données enregistré sur le disque ou envoyé sur internet.

Lorsque l'objet est ensuite désérialisé,le flux de données venant d'un fichier donne un flux d'octets qui donne une valeur aux champs et propriétés de l'objet, on obtient un objet identique à l'objet d'origine.

Vous pouvez aussi sérialiser un objet et le transporter sur Internet entre un client et un serveur à l'aide du protocole HTTP. À l'autre extrémité, la désérialisation reconstruit l'objet à partir du flux.


XV-H-2. Exemple 1 : Sérialisation binaire

Créons une mini Classe:

<Serializable()> Public Class Compta
Public Total As Double 
Public Taux As Double
End Class

Notons que pour que la classe soit sérialisable , il faut ajouter

<Serializable()>.
L'attribut Serializable indique donc au compilateur que tout ce que contient la classe peut être conservé dans un fichier.

  • L'attribut NonSerialized peut être utilisé pour marquer les membres de la classe qui ne doivent pas être conservés.
  • Pour empêcher la sérialisation d'un membre Customer par exemple:
    
     <NonSerialized()> Public Customer As String
    

XV-H-3. Sérialisation

Dans le corps du programme, il faut mettre:

Imports System.IO
Imports System.Runtime.Serialization.Formatters.binary
Dans ce cas, vous utilisez un flux de sortie et un formateur binaire pour enregistrer l'objet dans un format binaire.

Dans l'entête du module créons une objet MyCompta:

Private myCompta As New Compta
Donnons des valeurs a ses membres.

myCompta.Taux = 2
myCompta.Total = 100
Si on quitte le programme, les valeurs sont perdues!!! On va donc les enregistrer dans un fichier "compta.bin"

Dim myFileStream As Stream = File.Create("Compta.bin")
Dim serializer As New BinaryFormatter
serializer.Serialize(myFileStream, myCompta)
myFileStream.Close()
Et voilà un fichier compta.bin a été crée sur le disque, il contient:

Bin=  ÿÿÿÿ Kserialisation, Version=1.0.1994.38183, Culture=neutral, PublicKeyToken=null serialisation.MaClasse 
Total Taux Y@ @ 
On a bien enregistré les valeurs des variables d'une instance dans un fichier.


XV-H-4. Déserialisation

Lors de la prochaine utilisation du logiciel,on crée de nouveau une instance de Compta:

Private myCompta As New Compta
Il faut ensuite 'récupérer' les valeurs de l'instance:

Dans Form1_Load par exemple:

Private Sub Form1_Load()
    If File.Exists("Compta.bin") Then
        Dim myFileStream As Stream = File.OpenRead("Compta.bin")
        Dim deserializer As New BinaryFormatter()
        myCompta = CType(deserializer.Deserialize(myFileStream), Compta)
        myFileStream.Close()
    End If
End Sub
A noter que vous devez d'abord vérifier que le fichier existe. S'il existe, créez une classe Stream pour lire le fichier binaire et une classe BinaryFormatter pour convertir le fichier. La méthode CType est utilisée pour la conversion du type d'objet Stream en type Compta.

Ca marche, on retrouve bien MyCompta.Taux=2

Bien sur , si on sérialise une nouvelle fois, cela écrase le précédent fichier.


XV-H-5. Exemple 2 : Sérialisation XML

Pour les applications Web ou les services Web XML, vous souhaiterez peut-être conserver l'objet dans un fichier XML à l'aide d'un format SOAP, ce qui facilite le partage de l'objet.

il faut charger dans les références la dll .Net

System.Runtime.Serialization.Formatters.Soap.dll
Ensuite Imports System.Runtime.Serialization.Formatters.Soap
Dim deserializer As New SoapFormatter
Remplacez "SavedCompta.bin" par "SavedCompta.xml".

Cela donne:

Imports System.IO
Imports System.Runtime.Serialization.Formatters.Soap
Private MyCompta As New MaClasse

Sérialisation:

MyCompta.Taux = 3
MyCompta.Total = 100
Dim myFileStream As Stream = File.Create("SaveCompta.xml")
Dim serializer As New SoapFormatter
serializer.Serialize(myFileStream, MyCompta)
myFileStream.Close()

Déserialisation:

Dim myFileStream As Stream = File.OpenRead("saveCompta.bin")
Dim deserializer As New soapFormatter
MyCompta = CType(deserializer.Deserialize(myFileStream), MaClasse)
MsgBox(MyCompta.Taux.ToString)
myFileStream.Close()
 

Si on regarde le fichier SavedCompta.xml (il est dans le répertoire bin) on voit que c'est de l'Xml:

<SOAP-ENV:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" 
xmlns:clr="http://schemas.microsoft.com/soap/encoding/clr/1.0" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Body>
<a1:MaClasse id="ref-1" xmlns:a1="http://schemas.microsoft.com/clr/nsassem/serialisation/serialisation%2C%20Version%3D1.0.1995.
30938%2C%20Culture%3Dneutral%2C%20PublicKeyToken%3Dnull">
<Total>100</Total>
<Taux>3</Taux>
</a1:MaClasse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

On se rend compte que la sérialisation binaire produit un fichier plus petit.


XV-H-6. Exemple 3 : Sérialisation d'une collection

On peut sérialiser un objet, on peut donc sérialiser toutes sortes objets (dit serialisable) , une image, une collection, un tableau....

Une collection est un objet, pour enregistrer son contenu, on peut donc le sérialiser.

Imports System.IO
Imports System.Collections
Imports System.Runtime.Serialization.Formatters.Binary
Imports System.Runtime.Serialization


Module MonModule
    
' Creation d'une hashtable contenant des noms et adresses.
        Public addresses As New Hashtable
        addresses.Add("Phil", "12 grand rue,69872")
        addresses.Add("Bob", "98 petite rue, 196")
        addresses.Add("Marie", "BP 89, Paris, 75200")

    Sub Serialisation()

        
        ' Pour serialiser la hashtable (et les clé/valeur),  
        Dim fs As New FileStream("MesAdresses.dat", FileMode.Create)
        Dim formatter As New BinaryFormatter
        Try
            formatter.Serialize(fs, addresses)
        Catch e As SerializationException
            Console.WriteLine("Echec serialisation. Cause: " &amp; e.Message)
            Throw
        Finally
            fs.Close()
        End Try
    End Sub



    Sub Deserialisation()
        ' Declaration de la HashTable.
        Dim addresses As Hashtable = Nothing
        Dim fs As New FileStream("DataFile.dat", FileMode.Open)
        Try
            Dim formatter As New BinaryFormatter

            addresses = DirectCast(formatter.Deserialize(fs), Hashtable)
        Catch e As SerializationException
            Console.WriteLine("Echec de deserialisation. Cause: " &amp; e.Message)
            Throw
        Finally
            fs.Close()
        End Try

    End Sub
End Module

XV-H-7. Exemple 4 : Sérialisation d'un tableau

 
Private MyCompta(10) As String
MyCompta(1) = "3"
MyCompta(2) = "100"
Sérialisation:

Dim myFileStream As Stream = File.Create("SaveCompta.xml")
Dim serializer As New SoapFormatter
serializer.Serialize(myFileStream, MyCompta)
myFileStream.Close()
Déserialisation:

Dim myFileStream As Stream = File.OpenRead("saveCompta.xml")
Dim deserializer As New soapFormatter
MyCompta = DirectCast(deserializer.Deserialize(myFileStream), String())
MsgBox(MyCompta(1).ToString)
myFileStream.Close()
Vous avez compris. Seule difficulté: le caste en String().

Bien sur, cela marche avec un tableau à plusieurs dimensions. Voyons les lignes à modifier

Private MyCompta(10,10) As String
MyCompta(1,1) = "3"
Dans la déserialisation:

MyCompta = DirectCast(deserializer.Deserialize(myFileStream), String(,))

XV-H-8. Exemple 5 : Sérialisation d'une collection générique

Ici nous enregistrons les données dans un fichier XML nommé "Meslivres.Xml" (il sera dans le répertoire bin/Debug lors de la conception, et dans le répertoire de l'exécutable si on installe le logiciel).

Les Sub SaveData et LoadData ont en paramètre un type de collection généric list( Of ClasseLivre) C'est une collection d'objets typés ClasseLivre .Ce paramètre est passé avec ByRef .

(Pour l'exemple complet voir le chapitre architecture)

Imports System.Xml.Serialization
Imports System.IO
 
Public Class AccesAuxDonnees
 
Public Sub SaveData(ByVal list As Collections.Generic.List(Of ClasseLivre))
' Déclaration
Dim serialXML As Xml.Serialization.XmlSerializer = Nothing
Dim streamIO As StreamWriter = Nothing
Try
serialXML = New Xml.Serialization.XmlSerializer(GetType(Collections.Generic.List(Of ClasseLivre)))
' Ouverture d'un flux en écriture sur le fichier XML des contacts
streamIO = New StreamWriter("Meslivres.Xml")
' Sérialisation de la liste des contacts
serialXML.Serialize(streamIO, list)
Catch ex As Exception
' Propagrer l'exception
Throw ex
Finally
' En cas d'erreur, n'oublier pas de fermer le flux en écriture si ce dernier est toujours ouvert
If streamIO IsNot Nothing Then
streamIO.Close()
End If
End Try
End Sub
 
Public Sub LoadData(ByRef list As Collections.Generic.List(Of ClasseLivre))
' Déclaration
Dim streamIO As StreamReader = Nothing
Dim serialXML As Xml.Serialization.XmlSerializer = Nothing
Try
' Tester l'existance du fichier
If System.IO.File.Exists("Meslivres.Xml") = True Then
serialXML = New Xml.Serialization.XmlSerializer(GetType(Collections.Generic.List(Of ClasseLivre)))
' Ouverture d'un flux en lecture sur le fichier XML des contacts
streamIO = New StreamReader("Meslivres.Xml")
' Désérialisation de la liste des contacts
list = CType(serialXML.Deserialize(streamIO), Collections.Generic.List(Of ClasseLivre))
End If
Catch ex As Exception
' Propagrer l'exception
Throw ex
Finally
' En cas d'erreur, n'oublier pas de fermer le flux en lecture si ce dernier est toujours ouvert
If streamIO IsNot Nothing Then
streamIO.Close()
End If
End Try
End Sub
End Class
Voila ce que donne le fichier XMl:

<?xml version="1.0" encoding="utf-8"?>
<ArrayOfClasseLivre xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<ClasseLivre>
<Titre>Livre1</Titre>
<Auteur>Auteur1</Auteur>
</ClasseLivre>
<ClasseLivre>
<Titre>Livre2</Titre>
<Auteur>Auteur2</Auteur>
</ClasseLivre>
<ClasseLivre>
<Titre>Titre3</Titre>
<Auteur>Auteur3</Auteur>
</ClasseLivre>
</ArrayOfClasseLivre>

XV-I. Surcharge

Quand on utilise une méthode avec des paramètres, il y a parfois possibilité d'utiliser, avec la même méthode, un nombre différent de paramètres ou des paramètres de nature différente: on appelle cela surcharger la méthode.

Chaque manière d'écrire les paramètres s'appelle une signature.

Exemple:

Voici une fenêtre MessageBox:


pour ouvrir une fenêtre MessageBox il y a 12 signatures, en voici 2:


Reponse= MessageBox.show(TexteAAfficher,Titre, TypeBouton etIcone, BoutonParDéfaut)
Ici on donne 4 paramètres.


Reponse= MessageBox.show(TexteAAfficher)
Ici 1 seul paramètre.

On voit qu'on peut appeler la méthode MessageBox.Show avec un nombre différent de paramètres.

Comme on ne peut pas connaître toutes les signatures, VB nous aide:

Si on tape R= MessageBox.show ( VB affiche dans un cadre une signature, de petites flèches permettent de faire défiler tous les autres signatures:

Quand on crée une Classe, il est bien sur possible d'écrire une property ou un constructeur qui accepte la surcharge:


XV-I-1. Surcharge en VB 2003

  1. On peut surcharger un constructeur.
    Pour cela il suffit de rajouter autant de procédure New que l'on veut avec pour chacune un nombre de paramètre différent (signatures différentes).

    Exemple: On peut surcharger un constructeur:
    
    
    Class Figure
    Sub New()
        Bla Bla
    End Sub
     
    Sub New( ByVal X As Integer, ByVal Y As Integer)
         Blabla
    End Sub. 
    End Class
    
    On peut donc instancier la classe correspondante de 2 manières:
    
    
    Dim A As New Figure    'Constructeur par défaut
    
    ou
    
    
    Dim A As New Figure(100,150)
    
  2. On peut surcharger une property.
    Pour cela il suffit de rajouter des procédure Property ayant le même nom de méthode avec pour chacune un nombre de paramètre différent (signature différente) On peut ajouter Overloads mais c'est facultatif.

    Exemple: surchargeons un membre:
    
    
    Class Figure
    Public Overloads Property Calcul()
        Bla Bla
    End Sub
     
    Public Overloads Property Calcul( ByVal X As Integer, ByVal Y As Integer)
         Blabla
    End Sub. 
    End Class
    
info C'est un bon exemple de polymorphisme.

XV-I-2. Surcharge en VB 2005 : nouveautés


  • Exemple: surchargeons l'opérateur +
    
    
    Public Structure height
        ...
        Public Shared Operator +(ByVal h1 As height, ByVal h2 As height)As height
            Return New height(h1.feet + h2.feet, h1.inches + h2.inches)
        End Operator
    End Structure
    
La routine doit être Shared, de plus si on surcharge certains opérateurs, il faut aussi surcharger leur inverse: si on surcharge '>' , il faut surcharger '<'.

Surcharge de IsTrue, IsFalse CType

Si on teste un boolean, il a la valeur True ou False.

Si par contre je crée une classe nommée 'Personne', je peux définir comment une instance sera considérée comme égale à True. Il faut surcharger l'opérateur IsTrue en lui indiquant dans quelle condition l'instance sera considérée comme =True:

Exemple:

J'ai une instance e de type Personne, si e.Present =True, dans ce cas je veux que e soit considéré comme True; il faut écrire dans la Classe 'personne':

Public Shared Operator IsTrue(ByVal e As Personne) As Boolean
If e Is Nothing Then
    Return False
Else
    Return e.Present
End If
End Operator
Pour définir l'opérateur IsFalse, c'est simple: c'est Not e
 
Public Shared Operator IsFalse(ByVal e As Personne) As Boolean
    Return Not e
End Operator

Ensuite je pourrais utiliser des instructions de la forme:

If e then.. 

Surcharge de CType:

Je peux définir dans une classe comment CType va fonctionner:

Pour cela dans la classe Personne, je vais définir les 3 possibilités:

Public Shared Widening Operator CType(ByVal e As Personne) As String
Return e.Nom + " " + e.Prenom
End Operator
 
Public Shared Widening Operator CType(ByVal  e As Personne) As Date
If e Is Nothing Then
    Return Nothing
Else
    Return e.DateDeNaissance
End If
End Operator
 
Public Shared Widening Operator CType(ByVal  e As Personne) As Boolean
    If e Is Nothing Then Return False Else Return e.Present
End Operator

Ainsi

CType(UnePersonne,String) retourne Nom Prenon

CType(UnePersonne,Date) retourne la date de naissance

CType(UnePersonne,Boolean) retourne True ou False.

Les exemples sont des surcharges, car le type des paramètres est modifié.

 

Les sources présentés sur cette page sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre cette page de présentation de ces sources constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © . Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts. Cette page est déposée à la SACD.

Vos questions techniques : forum d'entraide Accueil - Publiez vos articles, tutoriels, cours et rejoignez-nous dans l'équipe de rédaction du club d'entraide des développeurs francophones. Nous contacter - Copyright 2000..2005 www.developpez.com