In general, according to the OOP paradigm, my understanding of encapsulation basically says:
一般来说,根据OOP范例,我对封装的理解基本上是:
- If a member is private, it can only be accessed by the class.
- If a member is protected, it can only be accessed by the base class and any derived classes.
- If a member is public, it can be accessed by anyone.
如果成员是私有的,则只能由该类访问。
如果成员受到保护,则只能由基类和任何派生类访问。
如果某个成员是公开的,任何人都可以访问它。
If I have a nested class, can I declare a property to be accessible only to that class and the parent class it's nested within? For example:
如果我有一个嵌套类,我可以声明一个属性只能访问该类和它嵌套在其中的父类吗?例如:
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
In the example, I cannot directly access myNestedObject.myInt or myNestedObject.myDbl from an instance of ContainerClass if those members are Private or Protected. But suppose I don't want to make them Public, because then they are TOO exposed: they can be altered from anywhere, not just within a ContainerClass object. Declaring them Friend would still be too weak as that would allow them to be altered from anywhere within the application.
在示例中,如果这些成员是Private或Protected,我无法从ContainerClass的实例直接访问myNestedObject.myInt或myNestedObject.myDbl。但是假设我不想让它们公开,因为它们暴露在外:它们可以从任何地方改变,而不仅仅是在ContainerClass对象中。声明他们的朋友仍然太弱,因为这将允许他们在应用程序内的任何地方进行更改。
Is there any way to accomplish what I am going for here? If not, can anyone think of a more sensible way to achieve something like this?
有没有办法完成我要去的地方?如果没有,任何人都可以想到一种更明智的方式来实现这样的目标吗?
2 个解决方案
#1
There is no way of doing this directly with a combination of accessibility modifiers.
使用可访问性修饰符的组合无法直接执行此操作。
The best way I can think of doing this is as follows. It involves an extra level of indirection.
我能想到这样做的最好方法如下。它涉及额外的间接水平。
- Create a Nested Interface with Private accessibility. This will give only the Parent class and nested children access
- Add the fields you want access to to that interface
- Make the Nested class implement the interface
- Make all of the implementations have private accessibility
创建具有私有辅助功能的嵌套接口。这将仅提供Parent类和嵌套子级访问
将要访问的字段添加到该接口
使嵌套类实现接口
使所有实现都具有私有可访问性
Now the parent class and only the parent class will have access to those properties and methods.
现在,父类和只有父类才能访问这些属性和方法。
For Example:
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
#2
Based on JaredPar's answer, you could use a Private ChildClass but a Public Interface that reveals only what it sould show :
基于JaredPar的答案,您可以使用私有子类,但只能显示它可以显示的公共接口:
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
Usage :
Dim c As ParentClass.IChildClass = ParentClass.GetNewChild()
MessageBox.Show(c.i)
c.i = 2 ' Does not compile !
c.SomeSub()
#1
There is no way of doing this directly with a combination of accessibility modifiers.
使用可访问性修饰符的组合无法直接执行此操作。
The best way I can think of doing this is as follows. It involves an extra level of indirection.
我能想到这样做的最好方法如下。它涉及额外的间接水平。
- Create a Nested Interface with Private accessibility. This will give only the Parent class and nested children access
- Add the fields you want access to to that interface
- Make the Nested class implement the interface
- Make all of the implementations have private accessibility
创建具有私有辅助功能的嵌套接口。这将仅提供Parent类和嵌套子级访问
将要访问的字段添加到该接口
使嵌套类实现接口
使所有实现都具有私有可访问性
Now the parent class and only the parent class will have access to those properties and methods.
现在,父类和只有父类才能访问这些属性和方法。
For Example:
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
#2
Based on JaredPar's answer, you could use a Private ChildClass but a Public Interface that reveals only what it sould show :
基于JaredPar的答案,您可以使用私有子类,但只能显示它可以显示的公共接口:
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
Usage :
Dim c As ParentClass.IChildClass = ParentClass.GetNewChild()
MessageBox.Show(c.i)
c.i = 2 ' Does not compile !
c.SomeSub()