Cours VB.NETDate de mise à jour : 05/12/2010
XV-D. Les interfaces
XV-D-1. Définition : Interface et implémentation
XV-D-2. Les interfaces présentes dans les classes du Framework
XV-D-3. Les interfaces créées par le programmeur
XV-E. L'héritage
XV-E-1. Définition de l'héritage
XV-E-2. Membres de la classe dérivée
XV-E-2-a. Redéfinition de membres (Overrides)
XV-E-2-b. Surcharge de membres (Overloads)
XV-E-2-c. Cacher un membre de la classe de base (Shadows)
XV-E-2-d. Classe abstraite
XV-E-3. MyBase
XV-E-4. Constructeur dans une classe fille
XV-E-5. Héritage successif : exemple
XV-E-6. Création de classes à partir de classes du Framework
XV-E-7. Création de composants et héritage
XV-F. Les espaces de noms, portée des classes et membres (friend protected public private)
XV-F-1. Intérêts des espaces de noms (NameSpace)
XV-F-2. Pour créer une classe dans un espace de noms
XV-F-3. Portée des Classes, procédures, membres
XV-D. Les interfaces
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 :
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 :
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 :
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 :
Class MonEncrypte
Implements Cryptage
Event FinDecoding (ByVal RetVal As Integer) Implements Cryptage. FinDecoding
Function Encrypt (ByVal estring As String ) As String Implements Cryptage. Encrypt
End Function
Function Decrypt (ByVal dstring As String ) As String Implements Cryptage. Decrypt
End Function
Property CledeCodage () As Integer Implements Cryptage. CledeCodage
Get
End Get
Set
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.
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.
Dim C As New MonEncrypte ()
Dim I As Cryptage ()
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:
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
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:
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:
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'
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:
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:
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.
Public Class MaCollection
Inherits System. Collections . CollectionBase
Public Sub Add (ByVal a As 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:
Public Overrides Property OnPaint ()
MyBase. OnPaint
. . .
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:
Public Class Mere
Private _Nom As String
Public Sub New ( ByVal Nom As String )
_Nom= Nom
End Sub
End Class
Public Class Fille
Inherits Mere
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.
Class A
Public Overridable Sub F ()
Console. WriteLine (" A.F " )
End Sub
Public Overridable Sub G ()
Console. WriteLine (" A.G " )
End Sub
End Class
Class B
Inherits A
Public Overrides NotOverridable Sub F ()
Console. WriteLine (" B.F " )
End Sub
Public Overrides Sub G ()
Console. WriteLine (" B.G " )
End Sub
End Class
Class C
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.
Imports System. Collections
Public Class MyArray
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 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à:
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:
Protected Overrides Sub OnPaint (ByVal e As PaintEventArgs)
MyBase. OnPaint (e)
Dim myPen As New Pen (Color. Purple , 3)
e. Graphics . DrawRectangle (myPen, 3, 3, Me. Width - 6, Me. Height - 6)
End Sub
|
Si on compile cette Classe et qu'on ajoute le composant à un projet, on obtient le bouton suivant:
XV-F. Les espaces de noms, portée des classes et membres (friend protected public private)
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.
Namespace Prog1
Public Class PrintText
. . .
. . .
End Class
End Namespace
|
Ensuite dans le programme on peut utiliser
ou bien
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
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.
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.
|