Aller au menu - Aller au contenu

Icône Concepts avancés

Avatar
Mise à jour : 13/12/2010
Difficulté : Facile Facile Creative Commons BY-NC-SA
23 410 visites depuis 7 jours, dont 322 sur ce chapitre classé 14/786
La POO est un monde fabuleux, pour le moment elle doit vous sembler un peu trouble mais avec un peu de pratique, vous n'allez plus pouvoir vous en passer.

Mais bon, en attendant que tout ça devienne limpide, je vais vous apporter quelques notions nouvelles affin de vous permettre d'employer au mieux ces nouvelles connaissances.

Dans ce chapitre nous allons aborder quelques notions plus poussées et non pour le moins utiles.

Au menu : l'héritage, le polymorphisme, les collections, la surcharge d'opérateurs, les propriétés par défaut,les bibliothèques de classes et comment les utiliser, et les classes abstraites, soyons fous !

Bon appétit :)
Sommaire du chapitre :
Icône du chapitre
Chapitre précédent Sommaire Chapitre suivant

L'héritage

Premier concept important : l'héritage.

Même très important je dois dire. J'ai déjà tenté de vous exposer cette notion dans la partie sur la fenêtre mais ce n'était pas très judicieux, vous ne connaissiez pas la POO.

On va donc tout recommencer ici.

Bon, j'espère que les principes de création de classe et de programmation orientée objet sont acquis. Je sais que c'est une rude partie mais allez chercher un café et reprenez tout ça calmement.

Vous connaissez tous les mots Français "Héritage" et "Hériter", on peut le résumer par :

Citation : Wikitionnaire

Devenir propriétaire d’une chose par droit de succession.


Eh bien ce concept est quasiment le même en programmation à une petite nuance près. Dans la vraie vie un héritage transmet simplement une chose, en programmation l'héritage d'une classe va dupliquer cette dernière et donner ses caractéristiques à la classe qui hérite.

Un petit schéma pour être plus clair :)

Image utilisateur


Admettons que je veuille créer 2 classes comme ceci. Une classe guitare et une classe piano. Vous remarquez qu'elles présentent des similitudes, elles possèdent toutes les deux un attribut "Notes" qui va contenir le panel de notes que cet instrument peut jouer et un Sub "Joue" qui va lui permettre de produire un son. (Cas purement hypothétique, je ne vais pas vous demande de créer un orchestre en Visual Basic :) ).
En plus de ces deux éléments communs elles présentent des particularités spécifiques à leur type : la guitare aura en plus le nombre de cordes qu'elle possède et une fonction permettant d'utiliser le Vibrato. Le piano quand à lui, contiendra une variable comptant le nombre de touches qu'il possède et un Sub pour appuyer sur une touche spécifique.

Vous remarquez tout de suite que ces "similitudes" vont devoir être écrites en double ... Beaucoup de travail et de lignes pour rien.

C'est pour cela que dieu les programmeurs ont introduit le concept de l'héritage.

Regardez, si nous créons une troisième classe nommée "instrument" qui contiendra des membres communs à tous les instruments, comme l'attribut "Notes". Il serait si simple d'inclure cette classe dans les autres, de façon à bénéficier de ses caractéristiques.

Image utilisateur


C'est justement là toute la puissance de l'héritage. En une ligne de programmation nous allons pouvoir faire hériter nos classes Guitare et Piano de Instrument de façon à leur donner la possibilité d'utiliser ses membres.

Un héritage peut se faire sur plusieurs niveaux, il n'y a pas de limite. La classe instrument pouvait elle même hériter d'une classe de type "Chose" et ainsi de suite ...


Image utilisateur
Ici vous voyez l'héritage sur plusieurs niveaux : la voiture de police hérite de la classe "Voitures" qui hérite elle même de la classe "Véhicules".




Alors qu'est-ce que cette modification implique concrètement pour nos classes ?


Eh bien d'un point de vue extérieur à la classe, une fois instanciée par exemple, eh bien c'est transparent. C'est à dire qu'on ne saura pas si le membre de la classe auquel on va accéder appartient à la classe mère ou fille.

Par contre d'un point de vue interne à la classe, ça se complique. Nous allons devoir apprendre à jongler entre les membres appartenant a la classe fille où à la classe mère au travers de préfixes (du même type que Me).

Ce mot est MyBase.

Image utilisateur


Dans ce schéma, on se place du point de vue de la classe fille. Si depuis cette classe fille on débute une ligne par Me., les membres auxquels nous pourrons accéder seront ceux de de la classe fille et de toutes les classes dont elle hérite. En revanche, en utilisant MyBase. nous accèderons uniquement aux membres de la classe mère.

Cette informations va nous être très précieuse, surtout lorsque nous allons faire appel à des classes héritées qui ont besoin d'être instanciées.

Vous avez deux choix possible dans notre exemple : créer un constructeur dans "instrument" ou non. Si vous décidez de ne pas en mettre cette classe va être considérée comme abstraite (le chapitre d'après).
En revanche si vous décidez de mettre un constructeur, il va falloir instancier la classe mère au même moment que la classe fille.

Bon, arrêtons la théorie attaquons tout de suite la pratique pour que vous puissiez voir concrètement à quoi ça ressemble.

Code : VB.NET
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
Public Class Instrument

    Private _Notes() As Integer

    Sub New(ByVal Notes() as Integer)
        _Notes = Notes
    End Sub

End Class

Public Class Guitare
    Inherits Instrument 'Hérite d'instrument
    
    Private _NbCordes As Integer

    Sub New(ByVal Notes() As Integer, ByVal NbCordes As Integer)
        MyBase.New(Notes) 'On instancie la mère
        _NbCordes  = NbCordes
    End Sub

End Class


Dans ce petit bout de code j'ai crée deux classes : "Instrument" et "Guitare".

La classe Instrument est la classe mère, elle a un attribut _Notes et un constructeur.
La classe Guitare est la classe fille, elle a également un attribut _NbCordes et un constructeur.

La ligne Inherits Instrument indique que la classe hérite d'"Instrument". Et lors de l'instanciation de la classe fille, le constructeur de la classe mère est lui aussi appelé via MyBase.New(Notes) .

Les classes abstraites

Eh bien une classe abstraite est une classe ne pouvant pas être instanciée, autrement dit on ne peut pas créer d'objet à partir de ce moule.

Alors à quoi va-t-elle nous servir ?


Justement, nous allons lui trouver une utilité, et non des moindres.
Vous vous souvenez du principe de l'héritage ? (On vient de l'aborder :) ).
Elle va permettre de créer des classes dérivées, en clair, cette classe va seulement servir de base (une classe mère) pour des classes qui vont lui dériver.

Comme notre exemple sur les instruments, au début de cette partie. Une guitare, un piano, bref des instruments concrets, nous allons les instancier et les utiliser. Cependant la classe "instrument", la classe mère de tous les autres, nous aurions pu la définir en classe abstraite.

C'est vrai après tout, vous vous voyez créer un objet "instrument" :p .

Donc notre précédent code va devenir :

Code : VB.NET
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
Public MustInherit Class Instrument

    Private _Notes() As Integer

    Public Property Notes As Integer()
        Set(ByVal value() As Integer)
            _Notes = value
        End Set
        Get
            Return _Notes
        End Get
    End Property

End Class

Public Class Guitare
    Inherits Instrument 'Hérite d'instrument

    Private _NbCordes As Integer

    Sub New(ByVal Notes() As Integer, ByVal NbCordes As Integer)
        MyBase.Notes = Notes 'On spécifie la propriété Notes de la mère
        _NbCordes = NbCordes
    End Sub

End Class


Vous voyez que ici le mot clé MustInherit spécifié dans la déclaration de la classe (qui signifie en français "doit hériter" ou plutôt à traduire ici par "doit être hérité"), spécifie que cette classe sera abstraite, elle ne pourra pas être utilisée telle qu'elle.

Ma classe Guitare est donc ici pour hériter d'Instrument. Une fois la classe Guitare instanciée, on peut très bien accéder aux membres d'Instrument. MaGuitare.Notes(0) est tout à fait correct (où MaGuitare est mon objet crée).

Il existe toutefois une seconde utilisation possible pour les classes abstraites. En tant que bibliothèque de fonctions.

Je m'explique, plutôt que de placer toutes vos fonctions dans le fichier qui contient la fenêtre, il vous est possible de créer un fichier de classe, nommé "Fonctions" par exemple, et y inscrire des fonctions qui pourront être utilisées à partir de n'importe où dans votre programme.

Code : VB.NET
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
Public Class Fonctions

    Shared Function Somme(ByVal X As Integer, ByVal y As Integer) As Integer
        Return X + y
    End Function

    Shared Function Difference(ByVal X As Integer, ByVal y As Integer) As Integer
        Return X - y
    End Function

End Class


Ma classe Fonctions, j'ai retiré le mot MustInherit.

Vous vous apercevez que mes fonctions ne sont pas publiques ou privées mais Shared.

Le mot clé Shared signifiant Partagé en Français, indique que cette fonction peut être utilisée sans avoir besoin d'instancier la classe. Autrement dit, dans le programme on pourra utiliser Fonctions.Addition(1,2) où l'on veut.

Les avantages : la possibilité de regrouper des fonctions utiles dans le même fichier.
Les inconvénients : puisque la classe n'est pas instanciée, il n'est pas possible d'accéder à des membres externes à la fonction. Des variables globales ne pourront pas être utilisées par exemple.

Les évènements

Vous vous souvenez des évènements dans nos contrôles ?

Eh bien ici c'est le même principe.

Un évènement est une fonction appelée lorsque quelque-chose se produit. Ce quelque chos-, dans un contrôle commun est prédéfini le clic, le changement de texte ... Et on "écoute" cet évènement avec handles. Ici c'est pareil, on va écouter un évènement sur cet objet avec Handles.

Pour commencer, il faut spécifier ce qui va déclencher l'évènement à l'intérieur de notre classe.

Dans ma classe je déclare un timer en global avec WithEvents, ce qui signifie que je vais pouvoir écouter les évènements de cet objet. Vous avez déjà utilisé un timer en tant que contrôle (les contrôles étant d'office avec WithEvent) cette fois il ne sera visible que côté code.

Et je l'instancie puis le lance dans le constructeur avec une seconde en interval, j'utilise la fonction Start() pour le démarrer plutôt que Enable = true.

Dans l'évènement Tick du timer, j'incrémente un compteur, une fois arrivé à 10 je déclenche l'évènement.

Côté code ca nous donne ça dans notre classe :

Code : VB.NET
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
Private WithEvents _Tim As Timer
    Private _Compteur As Integer

    Sub New()
        _Tim = New Timer
        _Tim.Interval = 1000
        _Tim.Start()
        _Compteur = 0
    End Sub

    Public Event DixSecondes()

    Sub _Tim_Tick() Handles _Tim.Tick
        _Compteur += 1
        If _Compteur = 10 Then
            RaiseEvent DixSecondes()
        End If
    End Sub


Vous voyez pour commencer la déclaration des variables (compteur et timer). Puis le constructeur initialise, instancie et démarre tout ça.

Vient l'événement Tick du timer, je compte et je déclenche l'événement avec le mot clé RaiseEvent.

L'évènement déclenché doit être déclaré : Public Event DixSecondes(), en public pour pouvoir "l'écouter" de l'extérieur.

Allons du côté de notre fenêtre qui va instancier notre objet.

La classé déclarée en globale doit être faite avec le mot clé WithEvents également.

Code : VB.NET
1
2
3
4
5
6
7
8
9
Dim WithEvents MaClasse1 As MaClasse

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        MaClasse1 = New MaClasse1()
    End Sub

    Sub AttendsLesDixSecondes() Handles MaClasse1.DixSecondes
        MsgBox("Dix secondes que l'objet est crée")
    End Sub


Puis je l'instancie dans le form.

Pour finir j'ai écouté l'évènement avec Sub AttendsLesDixSecondes() Handles MaClasse1.DixSecondes. Lorsque les 10 secondes sont écoulées, je déclenche une msgBox.

Avec des arguments



Et on peut passer des arguments avec nos évènements :

Côté classe on déclare l'évènement avec

Code : VB.NET
1
Public Event DixSecondes(ByVal Message As String)


On voit qu'il attend un argument de type string.

DDonc lorsqu’on va l'appeler :

Code : VB.NET
1
RaiseEvent DixSecondes("Dix secondes que l'objet est crée")


Je lui passe mon argument.

Et finalement côté fenêtre, le handles de mon évènement s'effectue ainsi :

Code : VB.NET
1
2
3
Sub AttendsLesDixSecondes(ByVal Message As String) Handles MaClasse1.DixSecondes
        MsgBox(Message)
    End Sub


Et voilà, ca va vous être utile je pense, cette petite notion d'évènements.

La surcharge

Passons à la surcharge.

Encore une particularité de la POO qui va vous être fort utile.

Même si vous ne savez pas ce que ce mot signifie, je peux vous dire que vous y avez déjà été confrontés.

Souvenez-vous, lorsque vous passez des arguments à une fonction et que l'assistant de Visual Basic vous propose plusieurs possibilités de passer ces arguments :

Image utilisateur


Sur ce screen, vous voyez que l'infobulle spécifie "2 sur 15", j'ai choisi la seconde possibilité de donner les arguments sur 15 possibilité différentes. C'est cela la surcharge, pour la même fonction, avoir plusieurs "résultats" possible en fonction du passage des arguments.

Créons tout de suite un constructeur surchargé pour vous monter ce que cela implique :

Code : VB.NET
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
Public MustInherit Class Instrument

    Private _Notes() As Integer

    Public Property Notes As Integer()
        Set(ByVal value() As Integer)
            _Notes = value
        End Set
        Get
            Return _Notes
        End Get
    End Property

End Class

Public Class Guitare
    Inherits Instrument 'Hérite d'instrument

    Private _NbCordes As Integer

    Sub New()
        _NbCordes = 0
    End Sub

    Sub New(ByVal Notes() As Integer)
        MyBase.Notes = Notes
        _NbCordes = 0
    End Sub

    Sub New(ByVal Notes() As Integer, ByVal NbCordes As Integer)
        MyBase.Notes = Notes
        _NbCordes = NbCordes
    End Sub

End Class


Ici j'ai donc déclaré dans ma classe Guitare, 3 constructeurs différents, j'ai donc surchargé le constructeur.

Ce qui me donne le droit à cette infobulle lorsque je veux l'instancier : Image utilisateur

Deux fonctions avec des arguments de type différent apportent aussi une surcharge :

Code : VB.NET
1
2
3
4
5
6
7
8
9
Sub New(ByVal Notes() As Integer, ByVal NbCordes As Integer)
        MyBase.Notes = Notes
        _NbCordes = NbCordes
    End Sub

    Sub New(ByVal Notes() As Integer, ByVal NbCordes As String)
        MyBase.Notes = Notes
        _NbCordes = NbCordes
    End Sub


Ici le nombre de cordes est une fois un string, une autre fois un integer, la fonction appelée va dépendre du type passé lors de l'instanciation.

Surcharger la classe mère



Pour surcharger une méthode de la classe mère, la technique est presque la même. Il va juste falloir rajouter le mot clé Overloads devant la méthode de la classe fille. Ce qui nous donne :

Code : VB.NET
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
Public MustInherit Class Instrument

    Private _Notes() As Integer

    Public Property Notes As Integer()
        Set(ByVal value() As Integer)
            _Notes = value
        End Set
        Get
            Return _Notes
        End Get
    End Property

    Sub Joue()
        'Ding
    End Sub

End Class

Public Class Guitare
    Inherits Instrument 'Hérite d'instrument

    Private _NbCordes As Integer

    Sub New(ByVal Notes() As Integer, ByVal NbCordes As Integer)
        MyBase.Notes = Notes
        _NbCordes = NbCordes
    End Sub

    Overloads Sub Joue(ByVal Note As Integer)
        'Ding
    End Sub

End Class


J'ai bien rajouté Overloads devant la méthode Joue de la classe fille, et lors de son appel j'ai le choix entre les deux possibilités : avec ou sans argument.

Dernière chose : on peut "Bypasser" une méthode mère. Autrement dit, créer une méthode de la même déclaration dans l'enfant et spécifier que c'est cette dernière qui a la priorité sur l'autre. Cela grâce à Overrides .

Code : VB.NET
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
Public MustInherit Class Instrument

    Private _Notes() As Integer

    Public Property Notes As Integer()
        Set(ByVal value() As Integer)
            _Notes = value
        End Set
        Get
            Return _Notes
        End Get
    End Property

    Overridable Sub Joue()
        'Ding
    End Sub

End Class

Public Class Guitare
    Inherits Instrument 'Hérite d'instrument

    Private _NbCordes As Integer

    Sub New(ByVal Notes() As Integer, ByVal NbCordes As Integer)
        MyBase.Notes = Notes
        _NbCordes = NbCordes
    End Sub

    Overrides Sub Joue()
        MyBase.Joue() 'Ding de la mère
        'Ding
    End Sub

End Class


La méthode Joue de la fille prime sur la mère. Le mot clé Overrides dans la déclaration de la méthode fille est nécessaire, tout comme le mot clé Overridable dans la déclaration de la méthode mère.

Et j'ai pu utiliser MyBase.Joue() pour que la méthode mère soit quand même appelée.

La surcharge d'opérateurs et les propriétés par défaut

Dernière section de ce premier chapitre sur les notions avancées : la surcharge d'opérateurs et les propriétés par défaut.

Paramètres aux propriétés



Avant de comprendre les propriétés par défaut il faut juste que je vous montre comment utiliser un paramètre dans un propriété, ça me semble logique mais quelques lignes d'éclaircissement ne feront pas de mal. Admettons que je veuille accéder à un certain index dans un tableau à partir d'une propriété, je vais devoir passer un argument à cette dernière :

Code : VB.NET
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
Module Module1

    Sub Main()
        Dim MaClasse As New Classe
        Console.WriteLine(MaClasse.Variable(0))
        Console.Read()
    End Sub

End Module

Public Class Classe

    Dim _Variable() As String

    Sub New()
        _Variable = {"a", "b", "c", "d"}
    End Sub

    Property Variable(ByVal Index As Integer) As String
        Get
            Return _Variable(Index)
        End Get
        Set(ByVal value As String)
            _Variable(Index) = value
        End Set
    End Property

End Class


Ici (je ne devrais même plus avoir à vous expliquer le code je pense :p ), je demande lors de l'appel de la propriété, un paramètre spécifiant l'index, même principe qu'une fonction demandant des arguments : Property Variable(ByVal Index As Integer) As String .

Les propriétés par défaut



Les propriétés par défaut, vont vous permettre de vous soustraire à quelques lignes dans votre code source.
Ce concept a pour but d'attribuer à une certaine propriété la particularité d'être par "défaut".

Lorsque vous voudrez utiliser cette propriété vous n'autrez plus besoin d'écrire MaClasse.Variable(0) mais seulement MaClasse(0) .

A utiliser avec précaution si vous ne voulez pas vite être embrouillé :) .

Un simple mot suffit dans le code que je viens de faire, pour la spécifier en défaut :

Code : VB.NET
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
Module Module1

    Sub Main()
        Dim MaClasse As New Classe
        Console.WriteLine(MaClasse(0))
        Console.Read()
    End Sub

End Module

Public Class Classe

    Dim _Variable() As String

    Sub New()
        _Variable = {"a", "b", "c", "d"}
    End Sub

    Default Property Variable(ByVal Index As Integer) As String
        Get
            Return _Variable(Index)
        End Get
        Set(ByVal value As String)
            _Variable(Index) = value
        End Set
    End Property

End Class


Le mot clé Default spécifie quelle propriété doit être considérée comme celle par défaut.

Deux précautions à prendre : les propriétés par défaut doivent au moins attendre un argument. Et il ne peut y avoir qu'une seule propriété par défaut par classe (logique).


Surcharge d'opérateurs



Comme son nom l'indique, cette surcharge va être spécifique aux opérateurs : +, -, /, *, &, =, <, >, Not, And, et j'en passe ...

Vous savez déjà qu'ils n'ont pas la même action en fonction des types que vous utilisez.

Entre deux integers : 10 + 10 = 20
Entre deux strings : "Sal" + "ut" = "Salut"
Entre deux date : CDate("20/10/2010") + CDate("20/10/2010") = 20/10/201020/10/2010

Bref, rien à voir.

Apprenons a surcharger un opérateur pour notre classe pour la faire réagir avec ce dernier.

La ligne de déclaration d'une surcharge d'opérateur est un peu plus spécifique :

Code : VB.NET
1
Shared Operator +(ByVal Valeur1 As Classe, ByVal Valeur2 As Classe) As Classe


Tout d'abord, une surcharge d'opérateur doit être en Shared. Ensuite le mot Operator est suivi de l'opérateur que l'on souhaite surcharger. Ici c'est le "+". Suivi de deux paramètres (un de chaque côté du "+" :lol: ). Et le type qu'il retourne.

Exemple dans un petit programme :

Code : VB.NET
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
Module Module1

    Sub Main()

        Dim MaClasseBonjour As New Classe("Bonjour")
        Dim MaClasseSDZ As New Classe(" SDZ")
        Dim MaClasseBonjourSDZ As Classe = MaClasseBonjour + MaClasseSDZ

        Console.WriteLine(MaClasseBonjourSDZ.Variable)
        Console.Read()
    End Sub

End Module

Public Class Classe

    Dim _Variable As String

    Sub New(ByVal Variable As String)
        _Variable = Variable
    End Sub

    Property Variable As String
        Get
            Return _Variable
        End Get
        Set(ByVal value As String)
            _Variable = value
        End Set
    End Property

    Shared Operator +(ByVal Valeur1 As Classe, ByVal Valeur2 As Classe) As Classe
        Return New Classe(Valeur1.Variable + Valeur2.Variable)
    End Operator

End Class


J'ai donc surchargé l'opérateur "+" qui me permet d'additionner les valeurs de l'attribut Variable. Vous pouvez bien évidemment inventer d'autres choses à faire qu'une simple addition.

Puisque notre opérateur est Shared, on ne peut pas accéder aux attributs internes à la classe pendant son utilisation, il faut donc agir uniquement sur les paramètres qu'il récupère.

Les collections

Eh bien attaquons les collections.

Tout d'abord, et comme d'habitude, qu'est-ce qu'une collection ? A quoi ça va nous servir ?

Eh bien je vais d'abord vous exploser un problème. Vous avez un tableau que vous initialisez à 10 cases. Une case pour un membre par exemple. Si un membre veut être ajouté après la déclaration du tableau, vous allez devoir redéclarer un tableau avec une case de plus (on ne peut normalement pas redimensionner un tableau).

Une collection est sur le même principe qu'un tableau mais les éléments peuvent être ajoutés ou supprimés à souhait. Pour les zéros connaissant les listes chaînées, c'est le même concept.

Vous vous souvenez que nous déclarions un tableau en ajoutant accolé au nom de la variable deux parenthèses contenant le nombre d'éléments dans le tableau. Eh bien ici, ce n'est pas plus compliqué, mais ce n'est pas vraiment un tableau que l'on crée, c'est un objet de type collection.

La syntaxe d'instanciation sera donc :

Code : VB.NET
1
Dim MaListeDeClasses As New List(Of Classe)


Classe est une classe que j'ai crée pour les tests.
Le mot clé est List(Of TypeSouhaité).

Du même principe qu'un tableau qu'on remplissait à l'instanciation avec "= {1, 2, 3}", la liste peut se remplit manuellement ainsi :

Code : VB.NET
1
Dim MaListeDeClasses As New List(Of Classe) From {New Classe("1"), New Classe("2")}

Avec le mot clé From.

Cette collection va être vraiment utile, par de simples fonctions on va pouvoir ajouter un élément au bout où à un index spécifié, en retirer un, trouver un élément.

Exemple ici par un schéma :

Image utilisateur


  • J'initialise une liste de String. Cette liste va contenir des noms de films. Elle contient au début 4 films.
  • J'utilise la fonction Add sur cette liste, elle a pour effet d'ajouter au bout de la liste "Titanic".
  • J'utilise la fonction Insert, le premier argument est l'index où ajouter l'objet que l'on passe en second argument. Ici je le place en index 2. Sachant que L'index 0 l'aurait ajouté au début de la liste.
  • Puis j'utilise quelques fonctions que je vais vous détailler :
    • La fonction Contains effectue une recherche dans la liste pour trouver l'élément passé en argument. Si il est présent, elle renvoie True, sinon False.
    • IndexOf se présente de la même manière que Contains. Si elle ne trouve pas l'élément elle renvoie -1 sinon elle retourne l'index de l'élément. La fonction LastIndexOf existe aussi. Si des éléments sont présents en double, IndexOf retourne le premier, LastIndexOf le dernier.
    • Count quand à elle renvoie le nombre d'éléments dans la liste. A la même manière que Lenght sur un tableau.
      Le dernier index est donc MaListe.Count - 1

  • Puis j'utilise la fonction Remove pour supprimer l'élément Titanic.
  • Et la fonction RemoveAt sert aussi à supprimer un élément mais cette fois c'est l'index qui est passé en paramètre. J'aurais pu entrer l'index de Toy Story en dur (4) ou alors combiner la fonction IndexOf et RemoveAt comme fait ici.


Il existe beaucoup d'autres fonctions possibles sur les collections, je ne peux pas toutes les lister mais vous allez vite les découvrir grâce au listing qu'effectue Visual Studio lorsque vous écrivez quelque-chose.

Regardons un peu côté programmations :

Code : VB.NET
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
Module Module1

    Sub Main()

        Dim MaListeDeClasses As New List(Of Classe)
        MaListeDeClasses.Add(New Classe("Avatar"))
        MaListeDeClasses.Add(New Classe("Twilight 1"))
        MaListeDeClasses.Insert(0, New Classe("Titanic"))

        For Each MaClasse As Classe In MaListeDeClasses
            Console.WriteLine(MaClasse.Affiche)
        Next
        Console.Read()

    End Sub

End Module

Public Class Classe

    Private _Variable As String

    Sub New(ByVal Variable As String)
        _Variable = Variable
    End Sub

    Function Affiche() As String
        Return _Variable
    End Function

End Class


J'insère des éléments dans ma liste, et grâce à For Each, je parcours ces éléments.

J'espère que vous allez préférer ça aux tableaux =)

Bien évidemment vos listes peuvent être de tous les types, même des objets (comme ici dans l'exemple). Les avantages des listes sont multiples et très modulaires.

Les bibliothèques de classes

Lorsque vous créerez de gros objet, avec des dizaines de fonctions complexes à l'intérieur et qui peuvent être utilisés dans de multiples autres situations, vous voudrez sûrement sauvegarder ces derniers.

Vous avez donc deux possibilités. La première étant de simplement copier le fichier .vb contenant la classe et le coller dans votre nouveau projet.
La seconde étant de créer une bibliothèque de classes.

La bibliothèque de classes étant un nouveau projet qui aura pour but de créer une DLL, un fichier simple et compilé dans lequel toutes les classes que vous aurez développés dedans seront compilées et seront facilement réutilisables.

Un hic : vous ne pouvez plus modifier les classes une fois le fichier DLL compilé.

Les créer



Donc pour commencer votre bibliothèque, créer un nouveau projet -> Bibliothèque de clases.

Image utilisateur


Je vais l'appeler MesClasses

A l'intérieur de crée une classe :

Code : VB.NET
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
Public Class MaClasse

        Private _Variable As String

        Sub New(ByVal Variable As String)
            _Variable = Variable
        End Sub

        Function Affiche() As String
            Return _Variable
        End Function

    End Class

End Namespace


Remarquez le "Namespace", il permet de placer notre classe dans un namespace, ici celui de "MesClasses". On devra donc importer ce dernier à la même manière que System.IO par exemple.


Bien sûr si vous avez plusieurs classes a créer, soit vous les insérez dans le même fichier, soit vous créez un fichier par classe.

Ce type de projet n'est pas exécutable, il ne contient ni de Main, si de Load, il doit être obligatoirement utilisé par un autre projet.


Une fois votre classe crée et vérifiée, il va falloir générer le projet.

Pour ce faire, un clic droit sur le projet dans l'explorateur de solutions et "Générer".

Image utilisateur


La DLL est maintenant compilée.

Pour la retrouver, direction VosDocuments\Visual Studio 2010\Projects\MesClasses\MesClasses\bin\Debug.

Où MesClasses est le nom de votre projet. Si vous avez modifié la configuration de la génération, il est possible que la DLL se situe dans Release plutot que Debug.

Une fois dans ce répertoire donc, le fichier DLL s'est compilé et vous le retrouvez, gardez le bien au chaud, dans un répertoire contenant toutes vos bibliothèques, pourquoi pas.

Image utilisateur


Les réutiliser dans un projet



Alors, maintenant pour pouvoir réutiliser nos classes dans un projet il va falloir effectuer une petite manipulation, ajouter une référence.

Nous allons spécifier au projet d'utiliser en plus du framework qui est préincorporé par défaut, notre DLL contenant notre bibliothèque.

Un clic droit sur le projet (où l'on veut utiliser la bibliothèque cette fois puis "Ajouter une référence".

Image utilisateur


Dans l'onglet "Parcourir", recherchez votre DLL.

Image utilisateur


Puis ok.

Maintenant il va falloir importer le namespace.

Vous voyez que Visual Studio nous aide :

Image utilisateur


Code : VB.NET
1
Imports MesClasses


Et voilà votre bibliothèque est totalement utilisable.

Image utilisateur


En espérant que cela va pouvoir trouver une certaine utilité parmi vos projets :) .
Beaucoup de notions qui sont particulièrement spécifiques à la POO et peuvent vous être d'une grande aide dans certains cas particuliers.

Ne sous-estimez pas ces chapitres, même s'ils sont compliqués à appréhender ils sont très importants.
Chapitre précédent Sommaire Chapitre suivant

Partager

5 commentaires pour "Concepts avancés"
Note moyenne : 3.60 / 4 (543 votes)
Pseudo Commentaire
Hors ligne Mouhssine # Posté le 14/09/2010 à 11:15:30
Avatar

Avis : Décevant

Error 1 Method 'Public Sub _Tim_Tick()' cannot handle Event 'Public Event Tick(sender As Object, e As System.EventArgs)' because they do not have the same signature.
Hors ligne Ocarena # Posté le 23/09/2010 à 17:22:38

Ville : 40000
Pays : Maroc
Études : ESG Paris

Très Très Très Très mal expliquer le chapitre sur la POO vraiment du chinois pour ceux qui ont suivit le tuto depuis le début il se retrouverons perdus dans la POO.

Sinon joli travail, un tuto ne fait jamais de mal

  • PHP : 90%
  • XHTML : 95%
  • CSS : 90%
  • C : 80%
  • VB.NET : 70%
  • C++ : 60%
 
Hors ligne jamesst20 # Posté le 02/10/2010 à 23:59:45

Avis : Bon

Aww j'ai de la misère a comprendre....

Cependant j'ai un érreur lors de la création de la bibliothèque classe (En bas completement de la page) avec End Namespace

Merci
Hors ligne m@rg0d # Posté le 18/01/2011 à 19:49:53
Avatar

Avis : Décevant

Chapitre assez long je trouve, on aurait pu le diviser en deux avec un peu plus d'exemples pour faciliter la compréhension de ces notions effectivement "compliquées à appréhender".

L'informatique, ça fait gagner beaucoup de temps... à condition d'en avoir beaucoup devant soi ;)
 
Hors ligne saidox # Posté le 21/03/2011 à 23:46:46

Private _Notes() As Integer
j'ai pas compris,vous avez déclarer un tableau d'integer mais de quel taille ,est ce possible?les parenthèses dont vide!!!!!!
merçi pour le cours j'ai vraiment envie qu'il se compléte

Voir tous les commentaires