Domanda

In generale, secondo il paradigma OOP, la mia comprensione dell'incapsulamento dice sostanzialmente:

  1. Se un membro è privato, può accedervi solo dalla classe.
  2. Se un membro è protetto, è possibile accedervi solo dalla classe base e da qualsiasi classe derivata.
  3. Se un membro è pubblico, può accedervi da chiunque.

Se ho una classe nidificata, posso dichiarare che una proprietà è accessibile solo a quella classe e alla classe genitrice in cui è nidificata? Ad esempio:

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

Nell'esempio, non posso accedere direttamente a myNestedObject.myInt o myNestedObject.myDbl da un'istanza di ContainerClass se tali membri sono privati ??o protetti. Ma supponiamo che non voglia renderli pubblici, perché poi sono TROPPO esposti: possono essere modificati da qualsiasi luogo, non solo all'interno di un oggetto ContainerClass. Dichiararli Friend sarebbe comunque troppo debole in quanto ciò consentirebbe loro di essere modificati da qualsiasi parte dell'applicazione.

C'è un modo per realizzare quello che sto cercando qui? In caso contrario, qualcuno può pensare a un modo più sensato per ottenere qualcosa del genere?

È stato utile?

Soluzione

Non è possibile farlo direttamente con una combinazione di modificatori dell'accessibilità.

Il modo migliore in cui posso pensare di farlo è il seguente. Implica un ulteriore livello di riferimento indiretto.

  • Crea un'interfaccia nidificata con accessibilità privata. Ciò consentirà solo l'accesso alla classe Parent e ai figli nidificati
  • Aggiungi i campi a cui desideri accedere a quell'interfaccia
  • Rendi la classe Nidificata implementare l'interfaccia
  • Rendi tutte le implementazioni accessibili al privato

Ora la classe genitore e solo la classe genitore avranno accesso a tali proprietà e metodi.

Ad esempio:

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

Altri suggerimenti

In base alla risposta di JaredPar, è possibile utilizzare una ChildClass privata ma un'interfaccia pubblica che rivela solo ciò che dovrebbe mostrare:

    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

Utilizzo:

Dim c As ParentClass.IChildClass = ParentClass.GetNewChild()
MessageBox.Show(c.i)
c.i = 2 ' Does not compile !
c.SomeSub()
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top