Cours VB.NET

Image non disponible


précédentsommairesuivant

XV-D. Les interfaces

Image non disponible

XV-D-1. Définition : Interface et implémentation

Ce que je vois de l'objet, c'est son interface (le nom des propriétés, le nom des méthodes..) exemple: le nom de la méthode Clear fait partie de l'interface d'une ListBox. Par contre le code qui effectue la méthode (celui qui efface physiquement toutes les lignes de la ListBox), ce code se nomme implémentation, lui n'est ni visible ni accessible (Quand on est du coté du développeur qui utilise l'objet).

Un objet a donc une interface et une implémentation.

Quand maintenant on est du coté du créateur d'objet, dans un module de classe, si on a crée un objet et ses membres, sans le savoir, on crée en même temps l'interface et l'implémentation.

Mais il est possible de dissocier les 2.

Quel intérêt d'utiliser les interfaces?

Elles permettent d'organiser le code et de créer un 'contrat' sur les méthodes qui seront présentes dans les classes qui l'utilisent.

Vous pouvez développer des implémentations avancées pour vos interfaces sans endommager le code existant, ce qui limite les problèmes de compatibilité. Vous pouvez également ajouter de nouvelles fonctionnalités à tout moment en développant des interfaces et implémentations supplémentaires.

Différences entre Classe et Interface:

Tout comme les classes, les interfaces définissent un ensemble de propriétés, méthodes et événements. Cependant, contrairement aux classes, les interfaces n'assurent pas l'implémentation. Elles sont implémentées par les classes et définies en tant qu'entités distinctes des classes.

Les interfaces ne doivent pas être modifiées après publication. En effet, toute modification apportée à une interface publiée risque d'endommager le code existant. Il faut partir du principe qu'une interface est une sorte de contrat.(La partie qui publie une interface accepte de ne jamais modifier cette dernière et l'implémenteur accepte de l'implémenter exactement comme elle a été conçue.) Si on modifie l'interface, malgrés tout, il faut modifier l'implementation dans toutes les classes qui utilisent cette interface.

Comme d'habitude:

Il y a
  • les interfaces présentes dans les classes du Framework (IList, ICollection...)
  • les interfaces que vous créez de toutes pièces pour créer des objets.

Visual Basic .NET vous permet de définir des interfaces à l'aide de l'instruction Interface et de les implémenter avec le mot clé Implements.

XV-D-2. Les interfaces présentes dans les classes du Framework

Pour 'uniformiser' le comportement des objets, les interfaces sont largement utilisées dans VB.

Prenons l'exemple des collections:

Plutôt que de rendre communs à toutes les collections une méthode( Clear par exemple), VB donne la même interface à plusieurs types de Collections, ce qui uniformise la totalité des membres.

Les collections reposent sur l'interface ICollection, IList ou IDictionary. Les interfaces IList et IDictionary sont toutes les deux dérivées de l'interface ICollection.

Le nom des interfaces commence toujours par 'I'.

Dans les collections fondées sur l'interface IList ou directement sur l'interface ICollection (telles que Array, ArrayList, Queue ou Stack), chaque élément contient une valeur unique. Dans les collections reposant sur l'interface IDictionary (telles que Hashtable ou SortedList), chaque élément contient à la fois une clé et une valeur.

Détaillons l'interface Ilist:

L'interface Ilist permet de présenter une collection d'objets accessibles séparément par index.

Les méthodes de l'interface IList sont répertoriées ici.

Méthodes publiques

Add Ajoute un élément.
Clear Supprime tous les éléments.
Contains Détermine si la liste contient une valeur spécifique.
IndexOf Détermine l'index d'un élément spécifique.
Insert Insère un élément dans la liste à la position spécifiée.
Remove Supprime la première occurrence d'un objet spécifique.
RemoveAt Supprime l'élément correspondant à l'index spécifié.

Propriétés publiques

IsFixedSide Obtient une valeur indiquant si IList est de taille fixe.
IsReadOnly Obtient une valeur indiquant si IList est en lecture seule.
Item Obtient ou définit l'élément correspondant à l'index spécifié.

Les tableaux (Array) utilisent l'interface Ilist, mais aussi les collections (ArrayList) , des contrôles utilisent aussi cette interface (les ListBox, ComboBox), mais aussi les DataView...

Les ListBox possédent donc l'interface Ilist , on s'en doutait car on utilisait les méthodes Clear, Insert, Item...

Il y a plein d'autres interfaces.

Autre exemple: IEnumerable.

La Classe System.Array ( et d'autres ) implémente l'interface IEnumerable, ce qui permet d'utiliser une boucle For Each pour parcourir tous les éléments de l'Array.

(Voir le chapitre sur les Patron pour plus de détail)

XV-D-3. Les interfaces créées par le programmeur

De même que vous savez créer des classes, il est possible de créer de toutes pièces des interfaces.

Pour créer une Interface:
  • Dans un nouveau Module, définissez votre Interface en commençant par le mot clé Interface et le nom de l'interface et se terminant par l'instruction End Interface. Par exemple, le code suivant définit une Interface appelée Cryptage :
     
    Sélectionnez
    
    Interface Cryptage
    End Interface
  • Ajoutez des instructions définissant les propriétés, méthodes et événements pris en charge par votre Interface. Par exemple, le code suivant définit deux méthodes, une propriété et un événement :
     
    Sélectionnez
    
    Interface Cryptage
       Function Encrypt(ByVal estring As String) As String
       Function Decrypt(ByVal dstring As String) As String
       Property CledeCodage() As Integer
       Event FinDecoding(ByVal RetVal As Integer)
    End Interface

    L'interface est créée.

Pour implémenter une Interface
  • Si l'interface que vous implémentez ne fait pas partie de votre projet, ajoutez une référence à l'assembly qui contient l'interface.
  • Créez une nouvelle classe qui implémente votre Interface et ajoutez le mot clé Implements dans la ligne à la suite du nom de la classe. Par exemple, pour implémenter l'interface Cryptage , vous pouvez nommer la classe d'implémentation MonEncrypte, comme dans le code suivant :
     
    Sélectionnez
    
    Class MonEncrypte
    Implements Cryptage
    End Class
  • Ajoutez des procédures pour implémenter les propriétés, méthodes et événements de la classe :
     
    Sélectionnez
    
    Class MonEncrypte
       Implements Cryptage
       Event FinDecoding(ByVal RetVal As Integer) Implements Cryptage.FinDecoding
    
       Function Encrypt(ByVal estring As String) As String Implements Cryptage.Encrypt
          ' Placer le code de cryptage ici.
       End Function
       Function Decrypt(ByVal dstring As String) As String Implements Cryptage.Decrypt
          ' Placer le code de décryptage ici.
       End Function
            
       Property CledeCodage() As Integer Implements Cryptage.CledeCodage
          Get
             'Placer ici le code qui retourne la valeur de la propriété.
          End Get
          Set
             'Placer ici le code qui donne une valeur à la propriété.
          End Set
       End Property
    End Class 

Noter que :

Pour chaque membre implémenté dans ce code, une instruction Implements indique le nom de l'interface et du membre implémenté.

Tous les membres de l'interface doivent être implémentés.

Enfin utiliser la classe MonEncrypte dans votre programme.

 
Sélectionnez

Dim C As New MonEncrypte()
C.CledeCodage=3
Dim ChaineEncryptée As String= C.Encrypt( "ChaineAEncrypter")

Ou

Il faut créer une instance de la classe qui implémente MonEncrypte, crée une variable du type de l'interface, qui associe un gestionnaire d'événements à l'événement déclenché par l'instance, qui définit une propriété et exécute une méthode via l'interface.

 
Sélectionnez

Dim C As New MonEncrypte() 'Classe
Dim I As Cryptage()'Variable d'interface (ne pas mettre de 'New'
I=C
I.CledeCodage=3
Dim ChaineEncryptée As String = I.Encrypt( "ChaineAEncrypter")

Les 2 versions marchent.

S'il y a un RaiseEvent dans une procédure qui déclenche un évènement de la classe il faut aussi ajouter une ligne AddHandler.

Il peut y avoir héritage de plusieurs interfaces:

 
Sélectionnez

Interface IComboBox
   Inherits ITextBox, IListBox 
End Interface 
Public Class EditBox
   Inherits Control
   Implements ITextBox
   Implements IListBox
   Public Sub Paint()Implements ITextBox.Paint
      ...
   End Sub
   Public Sub Bind(b As string) Implements IListBox.Clear
   End Sub
End Class
 

XV-E. L'héritage

Image non disponible

XV-E-1. Définition de l'héritage

A partir d'une classe existante, la classe de base (ou classe mère), on peut créer une nouvelle classe,la classe dérivée (ou classe fille) qui héritent des propriétés de la classe de base. La classe fille peut être modifiée.

Exemple:

Soit la Classe 'Animal', on peut créer une Classe 'Cheval' qui aura toutes les propriétés de 'Animal'.

La Classe 'Cheval' est un 'Animal'. Quant on peut dire 'est un', il s'agit bien d'héritage.

Une classe peut hériter d'une autre classe, il suffit d'utiliser :'Inherits'

Inherits permet de déclarer une nouvelle classe,la classe dérivée (ou classe fille), basée sur une classe existante, la classe de base (ou classe mère) . Les classes dérivées héritent des propriétés, des méthodes, des événements, des champs et des constantes de la classe de base et peuvent les étendre.

Voici une classe de base:

 
Sélectionnez

Class Salarié1
Public Property SalaireAnnuel() As Integer
...
End Property 

End Class

Créons une classe dérivée qui hérite de Salarié1:

 
Sélectionnez

Public Class Salarié2
Inherits Salarié1
 
End Class

On peut ajouter:

MustInherit: Cela donne une classe non instanciable, on ne peut pas créer d'objet avec!! Alors à quoi cela sert!! A fournir une base pour des classes qui en hériteront. on appelle ces classes des classes abstraites.

NotInheritable: Cette classe ne peut-être héritée.

XV-E-2. Membres de la classe dérivée

La classe fille possède tous les membres de la classe mère.

Cela si le membre est 'Protected' ou 'Public'; pas s'il est Private.

Exemple:Une variable 'Privat'e n'est pas visible dans la Classe fille.

Une variable 'Public' est visible dans la Classe fille, mais aussi par l'utilisateur de l'objet.

Une variable 'Protected' est visible dans la Classe fille mais pas à l'extérieur.

Dans la classe Salarié2 on peut utiliser la méthode SalaireAnnuel.

Il est possible de rajouter des membres propre à la classe fille, mais aussi de redéfinir, de surcharger ou de masquer des membres de la classe mère.

XV-E-2-a. Redéfinition de membres (Overrides)

Il est possible en plus de redéfinir (de substituer de remplacer) un des membres de la classe mère dans la classe fille.(de créer une nouvelle définition du membre dans la classe fille et uniquement pour cette classe fille) si besoin. Pour que cela marche il faut que le membre de la classe mère soit modifiable (overridable) et que le membre de même nom de la classe fille soit modifié (Overrides)

Dans la Classe fille (classe dérivée):

Overrides
Indique que cette procédure Sub substitue une procédure de même nom dans une classe de base. Le nombre et les types de données des arguments doivent correspondre exactement à ceux de la procédure de la classe de base. Dans la Classe mère (classe de base):

Overridable
Indique que cette procédure peut être substituée par une procédure de même nom dans une classe dérivée. Overridable est le paramètre par défaut.

NotOverridable
Indique que cette procédure ne peut pas être substituée dans une classe dérivée. NotOverridable est le paramètre par défaut d'une procédure qui ne se substitue pas à une procédure de classe de base.

MustOverride
Indique que cette procédure Sub n'est pas implémentée dans cette classe et qu'elle doit l'être dans une classe dérivée pour que cette classe puisse être créée.

Exemple:

Créons une Classe Salarié1 avec une méthode 'Salaire annuel sur 13 mois'

 
Sélectionnez

Class Salarié1
Public Overridable ReadOnly Property SalaireAnnuel() As Integer
Get
    SalaireAnnuel = SalaireMensuel * 13 
End Get
End Property 
End Class
 

Créons maintenant une classe Salarié2 qui hérite de toutes les propriétés public et protected de la classe salarié1 donc la méthode SalaireAnnuel qui est sur 12 mois:

 
Sélectionnez

Public Class Salarié2
Inherits Salarié1
Public Overrides ReadOnly Property SalaireAnnuel() As Integer 
Get 
    SalaireAnnuel = SalaireMensuel * 12 
End Get 
End Property 
End Class

Quand on instance un objet avec la classe Salarié1, si on utilise la méthode SalaireAnnuel() il sera calculer sur 13 mois.

Quand on instance un objet avec la classe Salarié2, si on utilise la méthode SalaireAnnuel() il sera calculer sur 12 mois.

Attention le membre substitué doit avoir la même signature (Les mêmes paramètres).

XV-E-2-b. Surcharge de membres (Overloads)

Cela crée plusieurs membres de même nom mais avec des signatures différentes. Il peut y avoir une version dans la classe de base et une version surchargée de même nom mais avec une signature différente dans la classe fille.

Overloads
Indique que ce membre surcharge une ou plusieurs membres définis avec le même nom dans une classe de base. La liste d'arguments de cette déclaration doit être différente de la liste d'arguments de chaque membre surchargé. Les listes doivent différer au niveau de leur nombre d'arguments, de leurs types de données ou des deux. Cela permet au compilateur de distinguer la version à utiliser.

Exemple:

 
Sélectionnez

Public Overloads ReadOnly Property SalaireAnnuel( Prime As Integer) As Integer 
Get 
    SalaireAnnuel = (SalaireMensuel * 12) + Prime 
End Get 
End Property 

Vous ne pouvez pas spécifier Overloads et Shadows dans la même déclaration.

XV-E-2-c. Cacher un membre de la classe de base (Shadows)

"Shadows"

Indique que ce membre cache un élément de programmation de même nom ou un ensemble d'éléments surchargés, dans une classe de base.
Vous pouvez occulter tout type d'élément déclaré par un autre type. Si vous masquez une procédure avec une autre procédure, les arguments et le type retourné n'ont pas besoin de correspondre à ceux de la procédure de la classe de base.
Un élément occulté est indisponible à partir de la classe dérivée qui l'occulte, à moins que l'élément d'occultation soit inaccessible, comme c'est le cas de Private.

XV-E-2-d. Classe abstraite

Une classe abstraite est une classe avec laquelle on ne peut pas créer (instancier) directement d'objet. Elle sert uniquement à créer des classes dérivées.

CollectionBase est une classe abstraite (ne pouvant pas être utilisée telle quelle), on peut créer une classe qui en hérite.

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.

 
Sélectionnez

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

XV-E-3. MyBase

Dans le membre de la classe fille, on peut avoir besoin d'appeler le membre de la classe mère; on le fait avec MyBase:

 
Sélectionnez

Public Overrides Property OnPaint()  'on redéfini OnPaint 
MyBase.OnPaint			     'on appelle le OnPaint de la Classe mère	
...				     'on ajoute de nouvelles choses	
End Property

Se souvenir que Me est l'instance en cours, MyClass est aussi l'instance en cours si la méthode est overridée.

XV-E-4. Constructeur dans une classe fille

Les membres privés de la classe mère, comme on l'a dit, ne sont pas accessibles à partir de la classe fille.

Seuls les membres 'Public' et 'Protected' de la classe mère sont accessibles à partir de la classe fille, il faut donc utiliser ces membres dans la classe fille.

Exemple avec un constructeur:

 
Sélectionnez


Public Class Mere
'Attribut privé
Private _Nom As String
 
'Constructeur
Public Sub New( ByVal Nom As String)
	_Nom=Nom   
End Sub
End Class
 
 
Public Class Fille
Inherits Mere
'Constructeur
Public New ( ByVal Nom As String)
	MyBase.New (Nom)
End Sub
End Class

On voit ici que dans la classe fille, on appelle le constructeur de la classe mère.

Car dans la classe fille _Nom de la classe mère n'est pas accessible.

Dans une clase fille, on passe donc les paramètres à la classe mère en utilisant les membres 'Public' ou 'Protected' de cette classe mère, on initialise en plus directement les attributs propres à la classe fille si ils existent.

XV-E-5. Héritage successif : exemple

Une classe peut hériter d'une classe qui en hérite d'une autre:

Prenons l'exemple suivant :

C hérite de B qui hérite de A, les membres sont hérités s'il sont Overridable.

 
Sélectionnez

Class A
Public Overridable Sub F() ' le membre F pourra être modifié dans une classe fille
Console.WriteLine("A.F")
End Sub

Public Overridable Sub G()'le membre G pourra être modifié dans une classe fille
Console.WriteLine("A.G")
End Sub
End Class

Class B
Inherits A	'Hérite de A
Public Overrides NotOverridable Sub F()	'On interdit la modification de F dans une Classe fille
Console.WriteLine("B.F")
End Sub
Public Overrides Sub G()
Console.WriteLine("B.G")
End Sub
End Class

Class C	'Hérite de B qui hérite de A
Inherits B
Public Overrides Sub G()
Console.WriteLine("C.G")
End Sub
End Class

En VB.Net une Classe ne peut hériter que d'une seule Classe.

XV-E-6. Création de classes à partir de classes du Framework

Il est possible de créer une classe qui hérite d'une classe du Framework.

Exemple d'une classe MyArray héritant de la Collection ArrayList; on peut dans la classe appeler des membres de la classe de base (MyBase.Add(S))ou modifier les membres de cette classe de base (ici on 'cache' les membres de la classe de base par Shadows et on crée ses propres membres.

 
Sélectionnez

Imports System.Collections
Public Class MyArray
     Inherits ArrayList 'MyArray héritant de la Collection ArrayList

    
     Public  Shadows Sub Add(ByVal S As Salarié) 
          MyBase.Add(S)        'On appelle la méthode Add de la classe de base (classe mère) 
     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 Class

XV-E-7. Création de composants et héritage

On a vu que dans la création de composants, on peut utiliser un composant qui existe déjà:

 
Sélectionnez

Public Class MonBouton
Inherits System.Windows.Forms.Button
End Class
 

Ici on crée un composant MonBouton qui hérite de Button; ce composant Monbouton fonctionne exactement comme Button (le bouton habituel).

Pour modifier l'apparence du bouton, il faut remplacer (Overrides) la méthode OnPaint de Button par la vôtre (celle-ci dessine le contrôle). Au sein de cette méthode, vous devez appeler la méthode OnPaint de la base qui dessine le bouton habituel, puis ajouter vos propres fonctions de dessin.

Il faut donc ajouter dans la classe MonBouton la procédure:

 
Sélectionnez

Protected Overrides Sub OnPaint(ByVal e As PaintEventArgs)
MyBase.OnPaint(e) 'Appel à la méthode de la classe de base, ce qui dessine le bouton
Dim myPen As New Pen(Color.Purple, 3)
e.Graphics.DrawRectangle(myPen, 3, 3, Me.Width - 6, Me.Height - 6) 'Ajoute un cadre sur le dessin du bouton
End Sub

Si on compile cette Classe et qu'on ajoute le composant à un projet, on obtient le bouton suivant:

Image non disponible

XV-F. Les espaces de noms, portée des classes et membres (friend protected public private)

Image non disponible

XV-F-1. Intérêts des espaces de noms (NameSpace)

On peut créer une Classe dans un espace de noms.

Le but de ces espaces de noms est d'éviter les conflits et ambiguïtés sur les objets.

Exemple: deux programmeurs Prog1 et Prog2 distribuent des classes qui sont empaquetées et distribuées respectivement dans les dll, Prog1.dll et Prog2.dll.

Les deux programmeurs ont défini une classe nommée PrintText. N'ayant aucune relation , ils l'ont appelée de la même manière!!

Si dans un programme incluant les 2 dll, vous utilisez la classe PrintText, VB ne saura pas s'il doit prendre la classe PrintText de Prog1.dll ou celle de Prog2.dll.

Si le premier programmeur crée ses classes dans un espace de noms appelé Prog1 et le second programmeur dans un espace de noms appelé prog2, les deux classes s'appelleront alors Prog1.PrintText et Prog2.PrintText, ce qui lève toute ambiguïté.

XV-F-2. Pour créer une classe dans un espace de noms

On crée une Classe, puis on ajoute le NameSpace sur la ligne dessus.

 
Sélectionnez

Namespace Prog1
Public Class PrintText
' définition de la classe
...
...
End Class
End Namespace

Ensuite dans le programme on peut utiliser

 
Sélectionnez

Prog1.PrintText

ou bien

 
Sélectionnez

Imports Prog1

puis PrintText

Un programme a son propre espace de nom (qui est le nom du programme): Si dans MyProgramme, il y a le NameSpace MySpace contenant la classe MyClasse, on peut utiliser

 
Sélectionnez

MyProgramme.MySpace.MyClasse

XV-F-3. Portée des Classes, procédures, membres

On savait que les procédures pouvaient être Public ou Privée.

En fait pour indiquer une portée, en particulier dans une classe, les membres peuvent être:

Public
Les procédures déclarées avec le mot clé Public ont un accès public. Il n'existe aucune restriction quant à l'accessibilité des procédures publiques.

Protected

Dans un module de classe:
Les procédures déclarées avec le mot clé Protected ont un accès protégé. Elles sont accessibles seulement à partir de leur propre classe ou d'une classe dérivée.

Friend
Les procédures déclarées avec le mot clé Friend ont un accès ami. Elles sont accessibles à partir du programme contenant leur déclaration et à partir de n'importe quel autre endroit du même assembly.

Protected Friend
Les procédures déclarées avec les mots clés Protected Friend ont l'union des accès ami et protégé. Elles peuvent être utilisées par du code dans le même assembly, de même que dans les classes dérivées. L'accès Protected Friend peut être spécifié uniquement pour les membres des classes.

Private
Les procédures déclarées avec le mot clé Private ont un accès privé. Elles ne sont accessibles qu'à partir de leur contexte de déclaration, y compris à partir des membres de types imbriqués, tels que des procédures.


précédentsommairesuivant

Vous avez aimé ce tutoriel ? Alors partagez-le en cliquant sur les boutons suivants : Viadeo Twitter Facebook Share on Google+   

  

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. 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'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.