2009-05-15 5 views
0

D'accord, c'est un peu une question noobish, mais j'ai couru à travers cela aujourd'hui et cela me laisse un peu perplexe POURQUOI ce serait comme ça.Utiliser le polymorphisme sur le membre de l'interface

Tenir compte de la structure suivante

Public Class Employee 
    Implements IPerson 

    Private _MyManager As Manager 
    Public Property MyManager() As Manager Implements IPerson.TheirLeader 
     Get 
      Return _MyManager 
     End Get 
     Set(ByVal value As Manager) 
      _MyManager = value 
     End Set 
    End Property 

End Class 

Public Class Manager 
    Implements IPerson, IAuthorityFigure 

    Private _MyBoss As Boss 
    Public Property MyBoss() As Boss Implements IPerson.TheirLeader 
     Get 
      Return _MyBoss 
     End Get 
     Set(ByVal value As Boss) 
      _MyBoss = value 
     End Set 
    End Property 

End Class 

Public Class Boss 
    Implements IPerson, IAuthorityFigure 

    'Implementation code here... 

End Class 

Public Interface IPerson 

    Property TheirLeader() As IAuthorityFigure 

End Interface 

Public Interface IAuthorityFigure 
    'Stuff here... 
End Interface 

Voici ma question: je suis désireux d'avoir chaque personne implémentent l'interface IPerson, si elle est un employé, patron, ou le gestionnaire. Cependant, ils ont chacun un attribut qui fait référence à leur leader (les employés ont un manager, les managers ont un patron, etc.). Chaque mise en œuvre de leur chef pourrait être potentiellement différent à part le fait qu'ils implémentent l'interface IAuthorityFigure. Je veux avoir l'IPerson interface avoir une propriété pour le IAuthorityFigure, mais il jette une erreur de compilateur pour moi quand j'implémente cette b/c le IAuthorityFigure n'est pas le même type que Boss ou Manager (même s'ils implémentent l'interface). Donc, je fais quelque chose de mal, ou est-ce une limitation de l'utilisation des interfaces par rapport aux classes abstraites? Si c'est une limitation, quelqu'un peut-il expliquer pourquoi c'est ainsi?

Merci!

Répondre

1

Vous ne faites rien de mal. Dans toutes les versions actuellement publiées de Visual Basic (et C#), l'implémentation de la méthode, propriété ou champ d'une interface doit correspondre exactement à la signature de l'interface. Il n'y a aucun moyen de contourner cela. Le meilleur que vous pouvez faire est d'avoir 2 propriétés, une qui implémente l'interface et une autre qui est utilisée pour retourner l'implémentation réelle.

Private _MyBoss As Boss 
Public Property TheirLeader() As IAuthorityFigure Implements IPerson.TheirLeader 
    Get 
      Return MyBoss 
    End Get 
    Set(ByVal value As IAuthorityFigure) 
      MyBoss = CType(value, IAuthorityFigure) 
    End Set 
End Property 

Public Property MyBoss As Boos 
    Get 
      Return _MyBoss 
    End Get 
    Set(ByVal value As Boss) 
      _MyBoss = value 
    End Set 
End Property 
+0

Excellente idée - Je n'ai pas pensé à cette approche. Dans ma situation utiliseriez-vous cette technique (en essayant d'imaginer s'il y aurait des ramifications de le faire). – Nathan

+0

@Nathan, oui j'utiliserais certainement cette technique dans votre situation. Quand je suis confronté à une implémentation concrète comme Employee, je sais que le "TheirLeader" est un Manager. Je ne veux pas ajouter beaucoup de distributions redondantes à mon code, donc je fais la propriété dual. – JaredPar

+1

Le setter de propriété d'implémentation d'interface (TheirLeader) doit prendre un IAuthorityFigure et être converti en Boss dans ce cas (ceci ne sera pas compilé, puisque le paramètre value n'est pas du bon type). Personnellement, je ne l'aime pas trop, car cela permet d'envoyer n'importe quel IAuthorityFigure et va casser à l'exécution s'il ne s'agit pas d'une instance Boss Selon le cas, MaybeLeader devrait être en lecture seule (qui prend soin de cela problème). Si ce n'est pas le cas, il y a un risque. –

0

Il serait utile que vous indiquiez le code définissant l'interface IPerson. Cependant, je suppose que vous avez besoin de lancer le gestionnaire et le patron comme IAuthorityFigure au lieu de leurs classes.

Questions connexes