IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

VBA Discussion :

Polymorphisme, implémentation [Débat]


Sujet :

VBA

  1. #21
    Membre émérite

    Profil pro
    Inscrit en
    Février 2005
    Messages
    1 751
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 1 751
    Points : 2 368
    Points
    2 368
    Par défaut
    Bonjour,

    J'ai un peu phosphoré à la question soulevée par Tonioyo: comment accéder aux méthodes/propriétés de la classe spécifique ?
    Citation Envoyé par Tonioyo Voir le message
    Avec Implements Un Lapin est un mamifère et un Raton-Laveur l'est aussi, jusque là ok.

    mais lorsque l'on dis : J'ai un mamifère (implémentation / New), c'est un lapin (Affectation de notre mamifère comme lapin). Si je veux accèder aux propriétés et méthodes de mon mamifère en VBA (tout du moins Access VBA), on a accès qu'aux propriétés et méthodes de notre mamifère ce qui est juste et faux à la fois car à partir de mamifère on devrait avoir accès à la partie mamifère et à la partie Lapin.
    En VBA, il faudrait poser le problème en passant par le type Object qui donne accès aux méthodes/propriétés de la classe instanciée (celle à laquelle s'applique New).

    J'ai un animal (Object) et c'est un lapin (New cLapin).
    Code VBA : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Dim oAnimal As Object
    Set oAnimal = New cLapin
    Si cet animal est effectivement un mammifère, alors on peut accéder aux méthodes/propriétés de mammifère que sa classe implémente.
    Code VBA : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    Dim oMammifère As iMammifère
     
    If (TypeOf oAnimal Is iMammifère) Then
        ' cet animal est un mammifère
        Set oMammifère = oAnimal
     
        MsgBox "Ce mammifère est un: " & TypeName(oMammifère) & vbCrLf & _
                "Voilà son cri: " & oMammifère.Cri
    End If
    Via la référence d'objet oAnimal, on peut aussi accéder aux méthodes/propriétés spécifiques de la classe cLapin:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    ' Le lapin peut bondir (méthode de la classe cLapin)
    oAnimal.Bondir

  2. #22
    Futur Membre du Club
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 6
    Points : 7
    Points
    7
    Par défaut Polymorphisme ou Implémentation?
    Salut à tous,
    Quelle passionnante discussion !
    Mais ces 2 fonctions MsExcel en sont-elles des exemples?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    INDEX("Matrice";NumLigne;NumCol)
    INDEX("Réf";NumLigne;NumCol;NumZone)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    RECHERCHE("ValCherchée";"PlageRecherche";"PlageRésultat")
    RECHERCHE("ValCherchée";"Matrice")
    Si oui, Polymorphisme ou Implémentation?
    à+

  3. #23
    Responsable
    Office & Excel


    Homme Profil pro
    Formateur et développeur chez EXCELLEZ.net
    Inscrit en
    Novembre 2003
    Messages
    19 122
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : Belgique

    Informations professionnelles :
    Activité : Formateur et développeur chez EXCELLEZ.net
    Secteur : Enseignement

    Informations forums :
    Inscription : Novembre 2003
    Messages : 19 122
    Points : 55 921
    Points
    55 921
    Billets dans le blog
    131
    Par défaut
    Tiens, je n'avais pas vu cette intervention sur RECHERCHE

    Pour moi, c'est du polymorphisme
    "Plus les hommes seront éclairés, plus ils seront libres" (Voltaire)
    ---------------
    Mes billets de blog sur DVP
    Mes remarques et critiques sont purement techniques. Ne les prenez jamais pour des attaques personnelles...
    Pensez à utiliser les tableaux structurés. Ils vous simplifieront la vie, tant en Excel qu'en VBA ==> mon tuto
    Le VBA ne palliera jamais une mauvaise conception de classeur ou un manque de connaissances des outils natifs d'Excel...
    Ce ne sont pas des bonnes pratiques parce que ce sont les miennes, ce sont les miennes parce que ce sont des bonnes pratiques
    VBA pour Excel? Pensez D'ABORD en EXCEL avant de penser en VBA...
    ---------------

  4. #24
    Responsable Access

    Avatar de Arkham46
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    5 865
    Détails du profil
    Informations personnelles :
    Localisation : France, Loiret (Centre)

    Informations forums :
    Inscription : Septembre 2003
    Messages : 5 865
    Points : 14 524
    Points
    14 524
    Par défaut
    Bjr,

    Je reviens un peu sur la limitation de ce polymorphisme.
    Je parle du fait qu'on ne peut pas partager une méthode de la classe mère.

    Je déroule un petit exemple à base de client et fournisseur :
    - Je souhaite pouvoir définir un nom et un prénom à mes fournisseur.
    - Je souhaite également avoir une fonction qui me donne le nom complet (concaténation de prénom + nom).
    - je ne veux pas avoir à maintenir cette fonction à plusieurs endroits car c'est la même pour tout mes types de contacts
    - par contre je veux pouvoir définir des méthodes qui vont s'exécuter différemment pour chaque type de contact : par exemple une méthode qui ajoute le contact dans la bonne table (et avec les bons champs) en fonction de son type.

    Je crée donc une classe d'interface clContact :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    Public ContactName As String
    Public ContactFirstName As String
     
    Public Function FullName() As String
    FullName = ContactFirstName & " " & ContactName
    End Function
     
    Public Sub Insert()
    End Sub
    Cette classe :
    - stocke le nom (ContactName) et le prénom (ContactFirstName)
    - contient la fonction FullName qui concatène prénom et nom
    - la fonction Insert qui est vide car elle sera créée dans chaque "sous-classe"

    Voici la classe clClient :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
     
    Implements clContact
    Private Parent As clContact
     
    Private Sub Class_Initialize()
    Set Parent = New clContact
    End Sub
     
    Private Property Get clContact_ContactFirstName() As String
    clContact_ContactFirstName = Parent.ContactFirstName
    End Property
     
    Private Property Let clContact_ContactFirstName(ByVal RHS As String)
    Parent.ContactFirstName = RHS
    End Property
     
    Private Property Let clContact_ContactName(ByVal RHS As String)
    Parent.ContactName = RHS
    End Property
     
    Private Property Get clContact_ContactName() As String
    clContact_ContactName = Parent.ContactName
    End Property
     
    Private Function clContact_FullName() As String
    clContact_FullName = Parent.FullName
    End Function
     
    Private Sub clContact_Insert()
    DoCmd.RunSQL "insert into table TClients values('" & Parent.ContactFirstName & "','" & Parent.ContactName & "')"
    End Sub
    Et presque la même chose pour la classe clFournisseur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
     
    Option Compare Database
    Option Explicit
     
    Implements clContact
    Private Parent As clContact
     
    Private Sub Class_Initialize()
    Set Parent = New clContact
    End Sub
     
    Private Property Get clContact_ContactFirstName() As String
    Parent.ContactFirstName = Parent.ContactFirstName
    End Property
     
    Private Property Let clContact_ContactFirstName(ByVal RHS As String)
    Parent.ContactFirstName = RHS
    End Property
     
    Private Property Let clContact_ContactName(ByVal RHS As String)
    Parent.ContactName = RHS
    End Property
     
    Private Property Get clContact_ContactName() As String
    clContact_ContactName = Parent.ContactName
    End Property
     
    Private Function clContact_FullName() As String
    clContact_FullName = Parent.FullName
    End Function
     
    Private Sub clContact_Insert()
    DoCmd.RunSQL "insert into table TFournisseurs values('" & Parent.ContactFirstName & "','" & Parent.ContactName & "')"
    End Sub
    Dans ces classes j'implémente la classe clContact, et donc je dois créer toutes les procédures de cette interface.
    Je déclare un objet Parent de type clContact, et j'initialise cet objet à l'initialisation de la classe (Class_Initialize).
    Il est alors possible d'utiliser cet objet Parent pour faire appel aux procédures et propriétés qu'on souhaite avoir dans la classe mère.

    Par contre la procédure Insert est "classique".
    Elle s'exécute dans le module de classe qui correspond au type de contact.

    Pour tester, une petite fonction :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
     
    Function TestPolymorphisme()
    ' Deux objets "contact"
    Dim oClient1 As clContact
    Dim oFournisseur1 As clContact
    ' Crée un client
    Set oClient1 = New clClient
    ' Crée un fournisseur
    Set oFournisseur1 = New clFournisseur
    ' Prénom et nom du client
    oClient1.ContactFirstName = "Jean"
    oClient1.ContactName = "Boulanger"
    ' Prénom et nom du fournisseur
    oFournisseur1.ContactFirstName = "Pierre"
    oFournisseur1.ContactName = "Petrain"
    ' Affichage des noms complets
    Debug.Print oClient1.FullName
    Debug.Print oFournisseur1.FullName
    ' Insertion des contacts
    oClient1.Insert
    oFournisseur1.Insert
    End Function
    La proécure FullName n'est donc écrite qu'une seule fois.
    C'est utile pour une procédure qu'on ne veut pas maintenir à différents endroits à coup de copier-coller au risque d'en oublier un.

    La procédure Insert est spécifique à chaque type de contact.
    Bien sûr l'exemple n'est pas très pertinant, il n'y a que le nom de table qui change, mais il pourrait y avoir beaucoup plus de différences : des noms de champs différents, des vérifications de données différentes, ...

    C'est pas très très joli de créer un objet Parent dans chaque objet pour lui envoyer les méthodes, mais ça marche.

    Amusez-vous bien avec le polymorphisme!

  5. #25
    Expert éminent sénior

    Avatar de Tofalu
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Octobre 2004
    Messages
    9 501
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : Associations - ONG

    Informations forums :
    Inscription : Octobre 2004
    Messages : 9 501
    Points : 32 311
    Points
    32 311
    Par défaut
    C'est pas très très joli de créer un objet Parent dans chaque objet pour lui envoyer les méthodes, mais ça marche.
    Ca transforme surtout le sens de la notion d'héritage (sens au sens sémantique et pas coté ... ok, je sais pas m'exprimer )

    C'est comme l'héritage dans une base de données relationnelle, on transforme le verbe "est un" par "a un"

    Le fournisseur est un contact DEVIENT le fournisseur a une fiche contact

    Mais y a pas le choix, et c'est pas vraiment handicapant

  6. #26
    Responsable Access

    Avatar de Arkham46
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    5 865
    Détails du profil
    Informations personnelles :
    Localisation : France, Loiret (Centre)

    Informations forums :
    Inscription : Septembre 2003
    Messages : 5 865
    Points : 14 524
    Points
    14 524
    Par défaut
    Citation Envoyé par Tofalu Voir le message
    Le fournisseur est un contact DEVIENT le fournisseur a une fiche contact
    en fait les deux :
    Le fournisseur est un contact et a une fiche contact

    on garde quand même le polymorphisme d'héritage (les deux objets sont déclarés as clContact), mais on rajoute une "fiche contact" pour les procédures communes

  7. #27
    Membre confirmé Avatar de Tonioyo
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2008
    Messages
    343
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Juin 2008
    Messages : 343
    Points : 518
    Points
    518
    Par défaut
    Je suis en train de me poser un petite question métaphysique :

    Implement ne serrait pas le même concept d'interface en java ?

    Un gros problème c'est qu'avec Implements en VBA on peut instancier des méthodes du coup on perds la définition d'interface.
    loi de LeBlanc : Plus tard signifie jamais. extrait de Coder proprement Auteur:Robert C. Martin

  8. #28
    Invité
    Invité(e)
    Par défaut
    Salut,

    Une utilisation du mot-clé Implements ici: [XL-2007] Module de classe et KeyPress

Discussions similaires

  1. Réponses: 12
    Dernier message: 01/07/2004, 11h03
  2. Réponses: 8
    Dernier message: 04/06/2004, 09h13
  3. Moteur physique : comment l'implémenter ?
    Par haypo dans le forum Algorithmes et structures de données
    Réponses: 15
    Dernier message: 17/12/2003, 12h56
  4. Réponses: 2
    Dernier message: 06/07/2002, 12h36
  5. Implémentation des fonctions mathématiques
    Par mat.M dans le forum Mathématiques
    Réponses: 9
    Dernier message: 17/06/2002, 16h19

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo