¿Hay alguna manera de hacer que un valor sea accesible solo para el padre de una clase anidada VB.NET?
-
22-07-2019 - |
Pregunta
En general, según el paradigma OOP, mi comprensión de la encapsulación básicamente dice:
- Si un miembro es privado, solo la clase puede acceder a él.
- Si un miembro está protegido, solo puede acceder a él la clase base y cualquier clase derivada.
- Si un miembro es público, cualquiera puede acceder a él.
Si tengo una clase anidada, ¿puedo declarar que una propiedad sea accesible solo para esa clase y la clase principal en la que está anidada? Por ejemplo:
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
En el ejemplo, no puedo acceder directamente a myNestedObject.myInt o myNestedObject.myDbl desde una instancia de ContainerClass si esos miembros son privados o protegidos. Pero supongamos que no quiero hacerlos públicos, porque entonces están DEMASIADOS expuestos: pueden modificarse desde cualquier lugar, no solo dentro de un objeto ContainerClass. Declararlos como amigos aún sería demasiado débil, ya que eso les permitiría modificarlos desde cualquier lugar dentro de la aplicación.
¿Hay alguna forma de lograr lo que estoy buscando aquí? Si no, ¿alguien puede pensar en una forma más sensata de lograr algo como esto?
Solución
No hay forma de hacerlo directamente con una combinación de modificadores de accesibilidad.
La mejor forma en que puedo pensar en hacer esto es la siguiente. Implica un nivel adicional de indirección.
- Crear una interfaz anidada con accesibilidad privada. Esto solo dará acceso a la clase Parent y a los hijos anidados
- Agregue los campos a los que desea acceder a esa interfaz
- Hacer que la clase Nested implemente la interfaz
- Hacer que todas las implementaciones tengan accesibilidad privada
Ahora la clase padre y solo la clase padre tendrán acceso a esas propiedades y métodos.
Por ejemplo:
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
Otros consejos
Basado en la respuesta de JaredPar, podría usar una ChildClass privada pero una interfaz pública que revela solo lo que debería mostrar:
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
Uso:
Dim c As ParentClass.IChildClass = ParentClass.GetNewChild()
MessageBox.Show(c.i)
c.i = 2 ' Does not compile !
c.SomeSub()