Home All Groups Group Topic Archive Search About

How to hide base class member variable in derived class (w/o shadows)?

Author
17 Jun 2009 8:52 PM
Joe Duchtel
Hello -

I have a base class that has some member variables I do not want to be
inherited or visible by any instance of that derived class.

Class cBase
  Public mVariable As String
  ...

Class cDerived
  Inherits cBase

  Hide mVariable   ' <<< Private Shadows mVariable As ... is not
working

The problem if I use Private Shadows in the derived class is that an
instance will still show the variable in the base class:
Dim lDummy As New cDerived
lDummy.mVariable will be mVariable of cBase.

I tried Protected in cBase but then I cannot see mVariable in other
derived classes anymore.

I realize that there is no data encapsulation in my example but there
is a (legacy) reason for that.  I would have the same problem if I
were to use an accessor or Property.

Is there any mechanism in VB.NET that will allow me to completely hide
a member variable of the base class in a particular derived class?

Thanks,
Joe

Author
17 Jun 2009 9:41 PM
Armin Zingler
Joe Duchtel wrote:
> Hello -
>
> I have a base class that has some member variables I do not want to be
> inherited or visible by any instance of that derived class.


You inherit everything from the base class.


Show quoteHide quote
> Class cBase
>  Public mVariable As String
>  ...
>
> Class cDerived
>  Inherits cBase
>
>  Hide mVariable   ' <<< Private Shadows mVariable As ... is not
> working
>
> The problem if I use Private Shadows in the derived class is that an
> instance will still show the variable in the base class:
> Dim lDummy As New cDerived
> lDummy.mVariable will be mVariable of cBase.


> I tried Protected in cBase but then I cannot see mVariable in other
> derived classes anymore.

Really? This works:

   Class cBase
      Protected mVariable As String
   End Class

   Class cDerived
      Inherits cBase
      Sub sdfsdf()
         mVariable = "sdf"    'works
      End Sub
   End Class


> I realize that there is no data encapsulation in my example but there
> is a (legacy) reason for that.  I would have the same problem if I
> were to use an accessor or Property.
>
> Is there any mechanism in VB.NET that will allow me to completely hide
> a member variable of the base class in a particular derived class?

Not that I know of.



Armin
Author
18 Jun 2009 12:49 AM
Joe Duchtel
Show quote Hide quote
On Jun 17, 5:41 pm, "Armin Zingler" <az.nos***@freenet.de> wrote:
> Joe Duchtel wrote:
> > Hello -
>
> > I have a base class that has some member variables I do not want to be
> > inherited or visible by any instance of that derived class.
>
> You inherit everything from the base class.
>
>
>
>
>
> > Class cBase
> >  Public mVariable As String
> >  ...
>
> > Class cDerived
> >  Inherits cBase
>
> >  Hide mVariable   ' <<< Private Shadows mVariable As ... is not
> > working
>
> > The problem if I use Private Shadows in the derived class is that an
> > instance will still show the variable in the base class:
> > Dim lDummy As New cDerived
> > lDummy.mVariable will be mVariable of cBase.
> > I tried Protected in cBase but then I cannot see mVariable in other
> > derived classes anymore.
>
> Really? This works:
>
>    Class cBase
>       Protected mVariable As String
>    End Class
>
>    Class cDerived
>       Inherits cBase
>       Sub sdfsdf()
>          mVariable = "sdf"    'works
>       End Sub
>    End Class
>
> > I realize that there is no data encapsulation in my example but there
> > is a (legacy) reason for that.  I would have the same problem if I
> > were to use an accessor or Property.
>
> > Is there any mechanism in VB.NET that will allow me to completely hide
> > a member variable of the base class in a particular derived class?
>
> Not that I know of.
>
> Armin- Hide quoted text -
>
> - Show quoted text -

Hello -

I understand inheritance and how Protected works but I was looking for
something outside of the derived class.  Here is a full example of
what I'm trying to do written out ...

Module Test
    Public Class cBase
        Public mA As String = String.Empty
        Public mB As String = String.Empty
    End Class

    Public Class cDerivedA
        Inherits cBase

        Private Shadows mA As String = String.Empty
    End Class

    Public Class cDerivedB
        Inherits cBase
    End Class

    Sub Main()
        Dim lDerivedAInstance As New cDerivedA
        lDerivedAInstance.mA = "THIS SHOULD NOT WORK!"
        lDerivedAInstance.mB = "OK"

        Dim lDerivedBInstance As New cDerivedB
        lDerivedAInstance.mA = "OK"
        lDerivedAInstance.mA = "OK"
    End Sub
End Module

The lDerivedAInstance.mA = "..." only works because it accesses the
instance of mA in cBase.  If I protect that in cBase, I cannot access
it through an instance of cDerivedB anymore.

Thanks!
Joe
Author
18 Jun 2009 1:13 AM
Armin Zingler
Joe Duchtel wrote:
> I understand inheritance and how Protected works but I was looking for
> something outside of the derived class.

I know, but you wrote

>> I tried Protected in cBase but then I cannot see mVariable in other
>> derived classes anymore.

I wasn't able to repro this problem. Anyway, it's not possible what you're
trying to do.

But why do you want to do it? If every car (base class) has wheels and an
engine, a BMW (derived class) doesn't have an engine only.


Armin
Author
18 Jun 2009 11:26 AM
Joe Duchtel
Show quote Hide quote
On Jun 17, 9:13 pm, "Armin Zingler" <az.nos***@freenet.de> wrote:
> Joe Duchtel wrote:
> > I understand inheritance and how Protected works but I was looking for
> > something outside of the derived class.
>
> I know, but you wrote
>
> >> I tried Protected in cBase but then I cannot see mVariable in other
> >> derived classes anymore.
>
> I wasn't able to repro this problem. Anyway, it's not possible what you're
> trying to do.
>
> But why do you want to do it? If every car (base class) has wheels and an
> engine, a BMW (derived class) doesn't have an engine only.
>
> Armin

Hello -

Sorry ... I guess I was not very clear in that first paragraph.  I
figured that this is not really supported.

I understand that this idea defies OOP to some extent but I have to
deal with some legacy code that I cannot break to make it work in a
better way.

Thanks!
Joe
Author
18 Jun 2009 12:03 PM
Patrice
Perhaps by using a real interface ? Not sure if it would break your existing
code ?

At some point you have either to accept glitches in your legacy design or
redesign to fit good practices...

--
Patrice


"Joe Duchtel" <duch***@gmail.com> a écrit dans le message de groupe de
discussion :
9cf40722-31af-4968-8d96-814ce089f***@k2g2000yql.googlegroups.com...
Show quoteHide quote
> On Jun 17, 5:41 pm, "Armin Zingler" <az.nos***@freenet.de> wrote:
>> Joe Duchtel wrote:
>> > Hello -
>>
>> > I have a base class that has some member variables I do not want to be
>> > inherited or visible by any instance of that derived class.
>>
>> You inherit everything from the base class.
>>
>>
>>
>>
>>
>> > Class cBase
>> > Public mVariable As String
>> > ...
>>
>> > Class cDerived
>> > Inherits cBase
>>
>> > Hide mVariable ' <<< Private Shadows mVariable As ... is not
>> > working
>>
>> > The problem if I use Private Shadows in the derived class is that an
>> > instance will still show the variable in the base class:
>> > Dim lDummy As New cDerived
>> > lDummy.mVariable will be mVariable of cBase.
>> > I tried Protected in cBase but then I cannot see mVariable in other
>> > derived classes anymore.
>>
>> Really? This works:
>>
>> Class cBase
>> Protected mVariable As String
>> End Class
>>
>> Class cDerived
>> Inherits cBase
>> Sub sdfsdf()
>> mVariable = "sdf" 'works
>> End Sub
>> End Class
>>
>> > I realize that there is no data encapsulation in my example but there
>> > is a (legacy) reason for that. I would have the same problem if I
>> > were to use an accessor or Property.
>>
>> > Is there any mechanism in VB.NET that will allow me to completely hide
>> > a member variable of the base class in a particular derived class?
>>
>> Not that I know of.
>>
>> Armin- Hide quoted text -
>>
>> - Show quoted text -
>
> Hello -
>
> I understand inheritance and how Protected works but I was looking for
> something outside of the derived class.  Here is a full example of
> what I'm trying to do written out ...
>
> Module Test
>    Public Class cBase
>        Public mA As String = String.Empty
>        Public mB As String = String.Empty
>    End Class
>
>    Public Class cDerivedA
>        Inherits cBase
>
>        Private Shadows mA As String = String.Empty
>    End Class
>
>    Public Class cDerivedB
>        Inherits cBase
>    End Class
>
>    Sub Main()
>        Dim lDerivedAInstance As New cDerivedA
>        lDerivedAInstance.mA = "THIS SHOULD NOT WORK!"
>        lDerivedAInstance.mB = "OK"
>
>        Dim lDerivedBInstance As New cDerivedB
>        lDerivedAInstance.mA = "OK"
>        lDerivedAInstance.mA = "OK"
>    End Sub
> End Module
>
> The lDerivedAInstance.mA = "..." only works because it accesses the
> instance of mA in cBase.  If I protect that in cBase, I cannot access
> it through an instance of cDerivedB anymore.
>
> Thanks!
> Joe
Author
18 Jun 2009 3:55 PM
Patrice
More specifically :

    Public Class cBase
        Public mA As String = String.Empty
        Public mB As String = String.Empty
    End Class
    Interface ICDerivedA
        Property mb() As String
    End Interface

    Public Class cDerivedA
        Inherits cBase
        Implements ICDerivedA
        Private Shadows mA As String = String.Empty
        Public Shadows Property mB() As String Implements ICDerivedA.mb
            Get
                Return MyBase.mB
            End Get
            Set(ByVal value As String)
                MyBase.mB = value
            End Set
        End Property
    End Class

    Public Class cDerivedB
        Inherits cBase
    End Class

    Sub Main()
        Dim lDerivedAInstance As ICDerivedA = New cDerivedA
        lDerivedAInstance.mA = "THIS SHOULD NOT WORK!" ' DOESN'T COMPILE
        lDerivedAInstance.mb = "OK"

        Dim lDerivedBInstance As New cDerivedB
        lDerivedBInstance.mA = "OK"
        lDerivedBInstance.mA = "OK"
    End Sub

But I'm not sure if it wouldn't break your existing code. Also you could
reverse the inheritance relation (as in your sample cBase handles all what
cDerivedA handles not the other way round) but once again we don't know how
it would impact your existing code...

Or make them properties (is this possible) and throw an exception to at
least prevent what you don't want at runtime or even add an "obsolete"
attribute to see if it prevents compiling.

At some point you'll have to weight living with those workarounds agaisnt
changing the design (this is not VB.NET legacy code ?)...

--
Patrice


"Patrice" <http://www.chez.com/scribe/> a écrit dans le message de groupe de
discussion : u$SWYzA8JHA.4***@TK2MSFTNGP02.phx.gbl...
Show quoteHide quote
> Perhaps by using a real interface ? Not sure if it would break your
> existing code ?
>
> At some point you have either to accept glitches in your legacy design or
> redesign to fit good practices...
>
> --
> Patrice
>
>
> "Joe Duchtel" <duch***@gmail.com> a écrit dans le message de groupe de
> discussion :
> 9cf40722-31af-4968-8d96-814ce089f***@k2g2000yql.googlegroups.com...
>> On Jun 17, 5:41 pm, "Armin Zingler" <az.nos***@freenet.de> wrote:
>>> Joe Duchtel wrote:
>>> > Hello -
>>>
>>> > I have a base class that has some member variables I do not want to be
>>> > inherited or visible by any instance of that derived class.
>>>
>>> You inherit everything from the base class.
>>>
>>>
>>>
>>>
>>>
>>> > Class cBase
>>> > Public mVariable As String
>>> > ...
>>>
>>> > Class cDerived
>>> > Inherits cBase
>>>
>>> > Hide mVariable ' <<< Private Shadows mVariable As ... is not
>>> > working
>>>
>>> > The problem if I use Private Shadows in the derived class is that an
>>> > instance will still show the variable in the base class:
>>> > Dim lDummy As New cDerived
>>> > lDummy.mVariable will be mVariable of cBase.
>>> > I tried Protected in cBase but then I cannot see mVariable in other
>>> > derived classes anymore.
>>>
>>> Really? This works:
>>>
>>> Class cBase
>>> Protected mVariable As String
>>> End Class
>>>
>>> Class cDerived
>>> Inherits cBase
>>> Sub sdfsdf()
>>> mVariable = "sdf" 'works
>>> End Sub
>>> End Class
>>>
>>> > I realize that there is no data encapsulation in my example but there
>>> > is a (legacy) reason for that. I would have the same problem if I
>>> > were to use an accessor or Property.
>>>
>>> > Is there any mechanism in VB.NET that will allow me to completely hide
>>> > a member variable of the base class in a particular derived class?
>>>
>>> Not that I know of.
>>>
>>> Armin- Hide quoted text -
>>>
>>> - Show quoted text -
>>
>> Hello -
>>
>> I understand inheritance and how Protected works but I was looking for
>> something outside of the derived class.  Here is a full example of
>> what I'm trying to do written out ...
>>
>> Module Test
>>    Public Class cBase
>>        Public mA As String = String.Empty
>>        Public mB As String = String.Empty
>>    End Class
>>
>>    Public Class cDerivedA
>>        Inherits cBase
>>
>>        Private Shadows mA As String = String.Empty
>>    End Class
>>
>>    Public Class cDerivedB
>>        Inherits cBase
>>    End Class
>>
>>    Sub Main()
>>        Dim lDerivedAInstance As New cDerivedA
>>        lDerivedAInstance.mA = "THIS SHOULD NOT WORK!"
>>        lDerivedAInstance.mB = "OK"
>>
>>        Dim lDerivedBInstance As New cDerivedB
>>        lDerivedAInstance.mA = "OK"
>>        lDerivedAInstance.mA = "OK"
>>    End Sub
>> End Module
>>
>> The lDerivedAInstance.mA = "..." only works because it accesses the
>> instance of mA in cBase.  If I protect that in cBase, I cannot access
>> it through an instance of cDerivedB anymore.
>>
>> Thanks!
>> Joe
>
>
Author
18 Jun 2009 6:37 PM
Joe Duchtel
Show quote Hide quote
On Jun 18, 11:55 am, "Patrice" <http://www.chez.com/scribe/> wrote:
> More specifically :
>
>     Public Class cBase
>         Public mA As String = String.Empty
>         Public mB As String = String.Empty
>     End Class
>     Interface ICDerivedA
>         Property mb() As String
>     End Interface
>
>     Public Class cDerivedA
>         Inherits cBase
>         Implements ICDerivedA
>         Private Shadows mA As String = String.Empty
>         Public Shadows Property mB() As String Implements ICDerivedA.mb
>             Get
>                 Return MyBase.mB
>             End Get
>             Set(ByVal value As String)
>                 MyBase.mB = value
>             End Set
>         End Property
>     End Class
>
>     Public Class cDerivedB
>         Inherits cBase
>     End Class
>
>     Sub Main()
>         Dim lDerivedAInstance As ICDerivedA = New cDerivedA
>         lDerivedAInstance.mA = "THIS SHOULD NOT WORK!" ' DOESN'T COMPILE
>         lDerivedAInstance.mb = "OK"
>
>         Dim lDerivedBInstance As New cDerivedB
>         lDerivedBInstance.mA = "OK"
>         lDerivedBInstance.mA = "OK"
>     End Sub
>
> But I'm not sure if it wouldn't break your existing code. Also you could
> reverse the inheritance relation (as in your sample cBase handles all what
> cDerivedA handles not the other way round) but once again we don't know how
> it would impact your existing code...
>
> Or make them properties (is this possible) and throw an exception to at
> least prevent what you don't want at runtime or even add an "obsolete"
> attribute to see if it prevents compiling.
>
> At some point you'll have to weight living with those workarounds agaisnt
> changing the design (this is not VB.NET legacy code ?)...
>
> --
> Patrice
>
> "Patrice" <http://www.chez.com/scribe/> a écrit dans le message de groupe de
> discussion : u$SWYzA8JHA.4***@TK2MSFTNGP02.phx.gbl...
>
>
>
> > Perhaps by using a real interface ? Not sure if it would break your
> > existing code ?
>
> > At some point you have either to accept glitches in your legacy design or
> > redesign to fit good practices...
>
> > --
> > Patrice
>
> > "Joe Duchtel" <duch***@gmail.com> a écrit dans le message de groupe de
> > discussion :
> > 9cf40722-31af-4968-8d96-814ce089f***@k2g2000yql.googlegroups.com...
> >> On Jun 17, 5:41 pm, "Armin Zingler" <az.nos***@freenet.de> wrote:
> >>> Joe Duchtel wrote:
> >>> > Hello -
>
> >>> > I have a base class that has some member variables I do not want to be
> >>> > inherited or visible by any instance of that derived class.
>
> >>> You inherit everything from the base class.
>
> >>> > Class cBase
> >>> > Public mVariable As String
> >>> > ...
>
> >>> > Class cDerived
> >>> > Inherits cBase
>
> >>> > Hide mVariable ' <<< Private Shadows mVariable As ... is not
> >>> > working
>
> >>> > The problem if I use Private Shadows in the derived class is that an
> >>> > instance will still show the variable in the base class:
> >>> > Dim lDummy As New cDerived
> >>> > lDummy.mVariable will be mVariable of cBase.
> >>> > I tried Protected in cBase but then I cannot see mVariable in other
> >>> > derived classes anymore.
>
> >>> Really? This works:
>
> >>> Class cBase
> >>> Protected mVariable As String
> >>> End Class
>
> >>> Class cDerived
> >>> Inherits cBase
> >>> Sub sdfsdf()
> >>> mVariable = "sdf" 'works
> >>> End Sub
> >>> End Class
>
> >>> > I realize that there is no data encapsulation in my example but there
> >>> > is a (legacy) reason for that. I would have the same problem if I
> >>> > were to use an accessor or Property.
>
> >>> > Is there any mechanism in VB.NET that will allow me to completely hide
> >>> > a member variable of the base class in a particular derived class?
>
> >>> Not that I know of.
>
> >>> Armin- Hide quoted text -
>
> >>> - Show quoted text -
>
> >> Hello -
>
> >> I understand inheritance and how Protected works but I was looking for
> >> something outside of the derived class.  Here is a full example of
> >> what I'm trying to do written out ...
>
> >> Module Test
> >>    Public Class cBase
> >>        Public mA As String = String.Empty
> >>        Public mB As String = String.Empty
> >>    End Class
>
> >>    Public Class cDerivedA
> >>        Inherits cBase
>
> >>        Private Shadows mA As String = String.Empty
> >>    End Class
>
> >>    Public Class cDerivedB
> >>        Inherits cBase
> >>    End Class
>
> >>    Sub Main()
> >>        Dim lDerivedAInstance As New cDerivedA
> >>        lDerivedAInstance.mA = "THIS SHOULD NOT WORK!"
> >>        lDerivedAInstance.mB = "OK"
>
> >>        Dim lDerivedBInstance As New cDerivedB
> >>        lDerivedAInstance.mA = "OK"
> >>        lDerivedAInstance.mA = "OK"
> >>    End Sub
> >> End Module
>
> >> The lDerivedAInstance.mA = "..." only works because it accesses the
> >> instance of mA in cBase.  If I protect that in cBase, I cannot access
> >> it through an instance of cDerivedB anymore.
>
> >> Thanks!
> >> Joe- Hide quoted text -
>
> - Show quoted text -

Hello -

This is actually pretty slick.  I have never used the Interface before
but it works beautifully.  Now I'll just have to figure out how to
make it work without breaking some of the legacy code.

I agree that at some point you just have to move forward but the
impact is huge ...

Thank a lot!
Joe
Author
19 Jun 2009 11:07 AM
Patrice
You are welcome and good luck. Just double check that the code you'll would
add to add these kind of workarounds won't make things even worst to update
in the future.

If you can change mA to a property, my personal prefererence would be likely
to add an Obsolete attribute in the derived class (not tried bu I don't see
why it wouldn't work) and always check that I have the same number of
warnings in my code...

Basically the code is unchanged and you have this under control before doing
a more drastic move...

--
Patrice