none
acceder a funcion de clase de nivel superior RRS feed

  • Pregunta

  • Tengo una clase... que dentro tiene una subclase que debe acceder a un valor calculado de la clase superior
    

    public Class A private _id as integer sub new _id=0 end sub ReadOnly Property IdIndividuo As Integer Get _Id += 1 Return _Id End Get End Property Public Class Individuo'Sub clase Private _Id As Integer .... Sub New() _Id = ACA NECESITO IDINDIVIDUO de la clase superior End Sub

    ...

    ...

    End Class end class


    NO ME PERMITE LEER/CALCULAR el valor de IdIndivicuo


    Hugo A. Gsell


    • Editado hagsell jueves, 7 de septiembre de 2017 15:21
    jueves, 7 de septiembre de 2017 15:17

Respuestas

  • "hagsell" preguntó:

    > Tengo una clase... que dentro tiene una subclase que debe acceder
    > a un valor calculado de la clase superior

    Hola:

    A ese tipo de clases normalmente se le suele denominar clases anidadas:

    Implementar clases anidadas

    >  Public Class Individuo'Sub clase
    >        Private _Id As Integer
    >         ....
    >        Sub New()
    >            _Id = ACA NECESITO IDINDIVIDUO de la clase superior
    >        End Sub
    >
    > NO ME PERMITE LEER/CALCULAR el valor de IdIndivicuo

    Tal cual has implementado las clases en el ejemplo que has expuesto en tu pregunta, no puedes acceder a la clase envolvente (la clase superior o 'A') desde la clase anidada (la "sub clase" o "Individuo") si no dispones de una referencia de aquella.

    En principio, se me ocurre que al constructor de la clase Individuo le pases una referencia válida de la clase A:

        Public Class Individuo 'Sub clase
    
            Private _Id As Integer
    
            Sub New(claseA As A)
                ' ACA NECESITO IDINDIVIDUO de la clase superior
                Me._Id = claseA._id
                
               ' A efectos de conocer el valor en tiempo de diseño.
               MessageBox.Show(_Id.ToString())
            End Sub
    
        End Class

    Y le pasarías una instancia de la clase A como indico a continuación:

        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    
            Dim a As New A()
            Dim n As Integer = a.IdIndividuo
            MessageBox.Show($"Propiedad A.IdIndividuo: {n}")
    
            ' Crear una nueva instancia de la clase A.Individuo para
            ' comprobar el valor de la propiedad A.IdIndividuo, el
            ' cual será un número más que el actual valor del campo
            ' _id de la clase A.
            '
            Dim ind As New A.Individuo(a)
    
        End Sub

    Si la clase Individuo no va a disponer de una interfaz pública, entiendo que no tiene ningún sentido que la declares como tal (Public), en cuyo caso la declararías como privada (Private). Si fuera éste el caso, entonces en su constructor le pasarías el valor del campo _id de la clase A:

        Private Class Individuo 'Sub clase
    
            Private _Id As Integer
    
            Sub New(id As Integer)
                ' ACA NECESITO IDINDIVIDUO de la clase superior
                Me._Id = id
            End Sub
    
        End Class

    Obviamente, al estar declarada como privada la clase anidada Individuo, no se podrán crear instancias de ella desde fuera de la clase envolvente, es decir desde fuera de la clase A.

    Edito:

    Ni que decir tiene que todo lo explicado anteriormente es por si no deseas utilizar campos compartidos (Shared), es decir, declarar el siguiente campo en la clase A:

    Public Class A
    
        Private Shared _id As Integer
    
    End Class
    

    Porque en este caso accederías a dicho valor compartido desde la clase Individuo tal y como indico a continuación:

        Private Class Individuo 'Sub clase
    
            Private _Id As Integer
    
            Sub New()
                ' ACA NECESITO IDINDIVIDUO de la clase superior
                _Id = A._id
                MessageBox.Show(_Id.ToString())
            End Sub
    
        End Class
    

    Si en dichas clases tienes todos los "cabos" bien atados, pues estupendo, pero como se te haya olvidado atar alguno de ellos, puede que tengas algún que otro dolor de cabeza con los valores de los campos compartidos, porque como su nombre indica, su valor estará compartido para todas aquellas instancias de la clase A actualmente válidas (que su valor no sea Nothing), existentes tanto en el subproceso principal de la aplicación como en aquellos otros subprocesos secundarios que se puedan crear desde la misma, y al estar declarado el campo compartido de lectura/escritura, está claro que su valor puede ser modificado.

    Si puedes evitar compartir campos, mucho mejor, pero si no hay más remedio que declararlos como tal, lo único que te puedo decir es que pongas especial cuidado en aquellas partes del código donde puede cambiar el valor del campo compartido.

    Advertido estás. ;-)

    Un saludo


    Enrique Martínez Montejo
    [MS MVP - Visual Studio y Tecnologías de Desarrollo]

    Nota informativa: La información contenida en este mensaje, así como el código fuente incluido en el mismo, se proporciona «COMO ESTÁ», sin garantías de ninguna clase, y no otorga derecho alguno. Usted asume cualquier riesgo al poner en práctica, utilizar o ejecutar lo recomendado o sugerido en el presente mensaje.

    Si esta respuesta le ha resultado útil, recuerde marcarla como satisfactoria.

    Si usas Visual Basic .NET y deseas ser productivo y feliz, se inteligente y activa la instrucción
    Option Strict.



    jueves, 7 de septiembre de 2017 16:45
    Moderador