Esiste un modo per rendere un valore accessibile solo al genitore di una classe nidificata VB.NET?
-
22-07-2019 - |
Domanda
In generale, secondo il paradigma OOP, la mia comprensione dell'incapsulamento dice sostanzialmente:
- Se un membro è privato, può accedervi solo dalla classe.
- Se un membro è protetto, è possibile accedervi solo dalla classe base e da qualsiasi classe derivata.
- 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?
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()