Pergunta

Em geral, de acordo com o paradigma OOP, o meu entendimento de encapsulamento basicamente diz:

  1. Se um membro é privado, só pode ser acessado pela classe.
  2. Se um membro é protegido, só pode ser acessado pela classe base e todas as classes derivadas.
  3. Se um membro é público, ele pode ser acessado por qualquer pessoa.

Se eu tiver uma classe aninhada, posso declarar uma propriedade para ser acessível apenas a essa classe e a classe pai é aninhada dentro? Por exemplo:

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

No exemplo, eu posso não diretamente myNestedObject.myInt de acesso ou myNestedObject.myDbl de uma instância de ContainerClass que esses membros são privada ou protegida. Mas suponha que eu não quero publicá-los, porque então eles estão muito expostos: eles podem ser alterados a partir de qualquer lugar, não apenas dentro de um objeto ContainerClass. Declarando-os amigo ainda estaria muito fraco como que lhes permitiria ser alterados a partir de qualquer lugar dentro do aplicativo.

Existe alguma maneira de realizar o que eu estou indo para aqui? Se não, alguém pode pensar de uma maneira mais sensata para conseguir algo assim?

Foi útil?

Solução

Não há nenhuma maneira de fazer isso diretamente com uma combinação de modificadores de acessibilidade.

A melhor maneira que eu posso pensar de fazer isso é o seguinte. Trata-se de um nível extra de engano.

  • Crie uma interface aninhada com Acessibilidade Privada. Isto dar-lhe apenas a classe Parent e acesso filhos aninhada
  • Adicione os campos que deseja o acesso à essa interface
  • Faça a classe aninhada implementar a interface
  • Faça todas as implementações têm acesso privado

Agora, a classe pai e só a classe pai terá acesso a essas propriedades e métodos.

Por exemplo:

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

Outras dicas

Com base na resposta de JaredPar, você poderia usar um Privada ChildClass mas uma interface pública que revela apenas o que sould 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()
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top