Existe-t-il un moyen de rendre une valeur accessible uniquement au parent d'une classe imbriquée VB.NET?
-
22-07-2019 - |
Question
En général, selon le paradigme de la programmation orientée objet, ma compréhension de l'encapsulation dit essentiellement:
- Si un membre est privé, il ne peut être consulté que par la classe.
- Si un membre est protégé, seul le membre de la classe de base et les classes dérivées peuvent y accéder.
- Si un membre est public, n'importe qui peut y accéder.
Si j'ai une classe imbriquée, puis-je déclarer une propriété accessible uniquement à cette classe et à la classe parente dans laquelle elle est imbriquée? Par exemple:
Public Class ContainerClass
Public Class NestedClass
Protected myInt As Integer ' <- this is what I am wondering about '
Protected myDbl As Double ' <- this is what I am wondering about '
Sub New()
myInt = 1
myDbl = 1.0
End Sub
End Class
Private myNestedObject As New NestedClass
' this function is illegal '
Public Sub GrowNestedObject(ByVal multiplier As Integer)
myNestedObject.myInt *= multiplier
myNestedObject.myDbl *= multiplier
End Sub
End Class
Dans l'exemple, je ne peux pas accéder directement à myNestedObject.myInt ou myNestedObject.myDbl à partir d'une instance de ContainerClass si ces membres sont privés ou protégés. Mais supposons que je ne veuille pas les rendre publics, car ils sont TROP exposés: ils peuvent être modifiés de n'importe où, pas seulement dans un objet ContainerClass. Les déclarer comme amis serait encore trop faible pour que leur modification puisse être modifiée à partir de n’importe où dans l’application.
Y a-t-il un moyen d'accomplir ce que je cherche ici? Sinon, est-ce que quelqu'un peut penser à un moyen plus raisonnable de réaliser quelque chose comme ça?
La solution
Il n’existe aucun moyen de le faire directement avec une combinaison de modificateurs d’accessibilité.
La meilleure façon de procéder est la suivante. Cela implique un niveau supplémentaire d'indirection.
- Créer une interface imbriquée avec accessibilité privée. Cela donnera uniquement l'accès à la classe parent et aux enfants imbriqués
- Ajoutez les champs auxquels vous souhaitez accéder à cette interface
- Amener la classe imbriquée à implémenter l'interface
- Assurez-vous que toutes les implémentations ont une accessibilité privée
Maintenant, la classe parent et seule la classe parent aura accès à ces propriétés et méthodes.
Par exemple:
Class Parent
Private Interface Interface1
ReadOnly Property Field1() As Integer
End Interface
Public Class Nested1
Implements Interface1
Private ReadOnly Property Field1() As Integer Implements Interface1.Field1
Get
Return 42
End Get
End Property
End Class
Sub New()
Dim child As Interface1 = New Nested1
Dim x = child.Field1
End Sub
End Class
Autres conseils
Sur la base de la réponse de JaredPar, vous pouvez utiliser une classe privée ChildClass, mais une interface publique ne révélant que ce qu'elle devrait afficher:
Public Class ParentClass
Public Interface IChildClass
ReadOnly Property i() As Integer
Sub SomeSub()
End Interface
Private Class ChildClass
Implements IChildClass
Public myInt As Integer
Public ReadOnly Property i() As Integer Implements IChildClass.i
Get
Return myInt
End Get
End Property
Public Sub SomeSub() Implements IChildClass.SomeSub
End Sub
End Class
Public Shared Function GetNewChild() As IChildClass
Dim myChild = New ChildClass()
myChild.myInt = 3
Return myChild
End Function
End Class
Utilisation:
Dim c As ParentClass.IChildClass = ParentClass.GetNewChild()
MessageBox.Show(c.i)
c.i = 2 ' Does not compile !
c.SomeSub()