Question

En général, selon le paradigme de la programmation orientée objet, ma compréhension de l'encapsulation dit essentiellement:

  1. Si un membre est privé, il ne peut être consulté que par la classe.
  2. Si un membre est protégé, seul le membre de la classe de base et les classes dérivées peuvent y accéder.
  3. 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?

Était-ce utile?

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()
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top