Hiding base-class member in derived-class
Hiding base-class member in derived-class
Hiding base-class member in derived-class
Hiding base-class member in derived-class
Hiding base-class member in derived-class
Hiding base-class member in derived-class Hiding base-class member in derived-class Hiding base-class member in derived-class Hiding base-class member in derived-class Hiding base-class member in derived-class Hiding base-class member in derived-class Hiding base-class member in derived-class Hiding base-class member in derived-class
Hiding base-class member in derived-class Hiding base-class member in derived-class
Hiding base-class member in derived-class
Go Back  Xtreme Visual Basic Talk > > > Hiding base-class member in derived-class


Reply
 
Thread Tools Display Modes
  #1  
Old 09-22-2006, 08:00 AM
00100b's Avatar
00100bHiding base-class member in derived-class 00100b is offline
Martian In Disguise

Retired Moderator
* Guru *
 
Join Date: May 2003
Location: Minneapolis, MN
Posts: 9,566
Default Hiding base-class member in derived-class


Having a base-class that contains a member that I don't want exposed in a derived-class, how would I go about hiding that member?

Say for example, I have a base-class containing:
Code:
Public Class IFoo
    Public Overridable Readonly Property Foobar() As String
        Get
            Return "Yep, this is a bogus property used for this example."
        End Get
    End Property
End Class
Now let's say for example, I have a derived-class:
Code:
Public Class CFoo
    Inherits IFoo

End Class
I thought (and this is where I am at fault), that I could hide IFoo.Foobar in the derived class using something like:
Code:
Public Class CFoo
    Inherits IFoo
    Private Overrides Readonly Property Foobar() As String
        Get
            ' This method does nothing in this derived-class.
        End Get
    End Property
End Class
But, I get the message:
Code:
'Private Overrides Readonly Property Foobar() As String' cannot 
override 'Public Overridable Readonly Property Foobar() As String' because 
they have different access levels.
So, my intended method is wrong (imagine that ).
Edit:
Oh, by the way. I thought that this method would work based on this snippet from the Help topic ".NET Framework Developer's Guide: Type Members"stating:
Quote:
Inheriting, Overriding, and Hiding Members
A derived type inherits all members of its base type; that is, these members are defined on and available to the derived type. The behavior or qualities of inherited members can be modified in two ways:
  • A derived type can hide an inherited member by defining a new member with the same signature. This might be done to make a previously public member private or to define new behavior for an inherited method that is marked as final.
  • A derived type can override an inherited virtual method. The overriding method provides a new definition of the method that will be invoked based on the type of the value at run time rather than the type of the variable known at compile time. A method can override a virtual method only if the virtual method is not marked as final and the new method is at least as accessible as the virtual method.
__________________
The only stupid question is the one that goes un-asked.

Last edited by 00100b; 09-22-2006 at 08:07 AM.
Reply With Quote
  #2  
Old 09-22-2006, 08:40 AM
reboot's Avatar
rebootHiding base-class member in derived-class reboot is offline
Keeper of foo

Retired Moderator
* Guru *
 
Join Date: Nov 2001
Location: Graceland
Posts: 15,614
Default

Interesting. Any chance this does what you want?

Private Shadows ReadOnly Property Foobar() As String
__________________
~ Quod non mortiferum, fortiorem me facit ~

Avatar by lebb
Reply With Quote
  #3  
Old 09-22-2006, 12:35 PM
00100b's Avatar
00100bHiding base-class member in derived-class 00100b is offline
Martian In Disguise

Retired Moderator
* Guru *
 
Join Date: May 2003
Location: Minneapolis, MN
Posts: 9,566
Default

Thank you.
__________________
The only stupid question is the one that goes un-asked.
Reply With Quote
  #4  
Old 09-22-2006, 01:21 PM
00100b's Avatar
00100bHiding base-class member in derived-class 00100b is offline
Martian In Disguise

Retired Moderator
* Guru *
 
Join Date: May 2003
Location: Minneapolis, MN
Posts: 9,566
Default

There must be something else that I'm missing.

If, in another class, I create an instance of the derived-class, the properties that were declared as "Private Shadows" in the class-block of the derived class still appear in the IntelliSense drop-down and indicate "Public Overridable" in the tool-tip popup associated with the IntelliSense drop-down.

I'm still playing the various keyword combinations, but if you have any other ideas...
__________________
The only stupid question is the one that goes un-asked.
Reply With Quote
  #5  
Old 09-22-2006, 02:27 PM
reboot's Avatar
rebootHiding base-class member in derived-class reboot is offline
Keeper of foo

Retired Moderator
* Guru *
 
Join Date: Nov 2001
Location: Graceland
Posts: 15,614
Default

Ugh... it was just a guess... apparently a bad one.
__________________
~ Quod non mortiferum, fortiorem me facit ~

Avatar by lebb
Reply With Quote
  #6  
Old 09-22-2006, 03:33 PM
AFterlife's Avatar
AFterlife AFterlife is offline
Contributor
 
Join Date: Dec 2003
Location: Mi
Posts: 654
Wink

What reboot suggested should work.It's in the scope of the property.The keyword is private. I think you had it set as a public property.
Code:
Public Class IFoo Private ReadOnly Property Foobar() As String Get Return "Yep, this is a bogus property used for this example." End Get End Property End Class Public Class CFoo Inherits IFoo Private Shadows ReadOnly Property Foobar() As String Get ' This method does nothing in this derived-class. Return "nothing" End Get End Property End Class

Actually you don't even need to shadow it if it's declared as private...
__________________
"Real knowledge is to know the extent of ones ignorance"

Last edited by AFterlife; 09-22-2006 at 03:42 PM.
Reply With Quote
  #7  
Old 09-22-2006, 03:43 PM
reboot's Avatar
rebootHiding base-class member in derived-class reboot is offline
Keeper of foo

Retired Moderator
* Guru *
 
Join Date: Nov 2001
Location: Graceland
Posts: 15,614
Default

That's the point, it's Public in the base class, he wants to make it Private in the derived class, which the article on MSDN he mentions says you can do. I read the article too, and it definitely reads that way, but makes no mention of how you do this.
__________________
~ Quod non mortiferum, fortiorem me facit ~

Avatar by lebb
Reply With Quote
  #8  
Old 09-22-2006, 03:49 PM
AFterlife's Avatar
AFterlife AFterlife is offline
Contributor
 
Join Date: Dec 2003
Location: Mi
Posts: 654
Default

That makes no sense to me.If you don't want it accessed in a derived class why declare it as public?
__________________
"Real knowledge is to know the extent of ones ignorance"
Reply With Quote
  #9  
Old 09-22-2006, 03:49 PM
reboot's Avatar
rebootHiding base-class member in derived-class reboot is offline
Keeper of foo

Retired Moderator
* Guru *
 
Join Date: Nov 2001
Location: Graceland
Posts: 15,614
Default

Maybe he didn't write/have access to the base class.
__________________
~ Quod non mortiferum, fortiorem me facit ~

Avatar by lebb
Reply With Quote
  #10  
Old 09-22-2006, 03:51 PM
shaul_ahuvaHiding base-class member in derived-class shaul_ahuva is offline
Ultimate Contributor

Retired Leader
* Expert *
 
Join Date: Jul 2003
Location: Camp Hill, PA
Posts: 1,992
Default

If you want to hide a member in the IDE, use the EditorBrowsable attribute.

You can’t change a member’s access level with Overrides or Shadows since the access level is part of the members signature. What essentially is happening is that you are creating a new property with the same name but with private access (therefore, a different signature) on the descendant type. If you were able to call the property on the descendant class from another class, you would get a MemberAccessException.

However, it seems as though the compiler is trying to be smart and display all of the accessible members for the type of home (variable, array element, etc.) that you're referencing. In this case, it skips over the first match (since it's private) and finds the base class's member (which is public). When your code is compiled a reference to the base type is used (again, the first accessible match in the hierarchy), which avoids the above exception but also causes confusion. This behavior is described very briefly here.

It doesn't make much sense to me - I would expect to get the first member (regardless of accessibility) that it finds in the hierarchy chain since I AM giving the compiler a specific type to use. IMHO, the compiler shouldn't attempt to guess what I mean - it should just do what I tell it to do. At the same time, VB compiler is designed to be very forgiving. Meh.



Edit by shaul_ahuva: Almost forgot - it looks like the context of that article 4B mentioned is MSIL, which is definitely not VB

The C# compiler also has the same behavior. Again, it just doesn't make sense to me.

Here is some sample code to demonstrate the difference between what the compilers allow and what MSIL allows:
Code:
Public Class Form1 Private Class BaseClass Public Sub Method() MessageBox.Show("BaseClass.Method") End Sub End Class Private Class VBShadowClass Inherits BaseClass Private Shadows Sub Method() MessageBox.Show("VBShadowClass.Method") End Sub Public Sub CallMethod() Method() End Sub End Class Private Class ILShadowClass Inherits BaseClass Private Shadows Sub Method() MessageBox.Show("ILShadowClass.Method") End Sub End Class Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Dim c As New VBShadowClass() c.Method() End Sub Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click Dim c As New ILShadowClass() c.Method() End Sub Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click Dim c As New VBShadowClass() c.CallMethod() End Sub End Class
The attached MSIL has been modified to use the ILShadowClass type token when calling ILShadowClass.Method (instead of the BaseClass token the compilers insists on using). It can be compiled with "ilasm WindowsApplication1.il.txt /output=WindowsApplication1.exe".
Attached Files
File Type: txt WindowsApplication1.il.txt (96.4 KB, 5 views)

Last edited by shaul_ahuva; 09-22-2006 at 05:21 PM.
Reply With Quote
  #11  
Old 09-22-2006, 04:01 PM
AFterlife's Avatar
AFterlife AFterlife is offline
Contributor
 
Join Date: Dec 2003
Location: Mi
Posts: 654
Default

If it's declared private in the base class can you still shadow it then within the derived class?
__________________
"Real knowledge is to know the extent of ones ignorance"
Reply With Quote
  #12  
Old 09-22-2006, 04:06 PM
shaul_ahuvaHiding base-class member in derived-class shaul_ahuva is offline
Ultimate Contributor

Retired Leader
* Expert *
 
Join Date: Jul 2003
Location: Camp Hill, PA
Posts: 1,992
Default

Quote:
Originally Posted by AFterlife
If it's declared private in the base class can you still shadow it then within the derived class?
You don't need Shadows in that case. Since the base member isn't accessible, VB ignores it.
Reply With Quote
  #13  
Old 09-22-2006, 05:37 PM
DeadalusHiding base-class member in derived-class Deadalus is offline
Promising Talent

Retired Moderator
* Guru *
 
Join Date: May 2002
Location: Brussels
Posts: 3,601
Default

Quote:
Originally Posted by reboot
That's the point, it's Public in the base class, he wants to make it Private in the derived class, which the article on MSDN he mentions says you can do. I read the article too, and it definitely reads that way, but makes no mention of how you do this.
You do it like you said. But the result is only that the original property is hidden inside the derived class's program text, since that's the scope of a private member.
Quote:
Originally Posted by shaul_ahuva
since the access level is part of the members signature.
No, it isn't part of the signature. That would mean that you can have two methods in the same class with the same name and parameter list and different accessibility, which you can't. It's simply an extra limitation .NET defines: that you cannot change the accessibility of a member that you override. Java does not impose this. There's something to be said for the .NET way, since breaking the is-a relationship in inheritance by effectively suppressing members is dangerous.
Edit: Oops, I was wrong about Java. The difference is that there you can give wider access to an overridden member, but weaker access is equally impossible.

Last edited by Deadalus; 09-22-2006 at 06:15 PM.
Reply With Quote
  #14  
Old 09-23-2006, 06:02 PM
shaul_ahuvaHiding base-class member in derived-class shaul_ahuva is offline
Ultimate Contributor

Retired Leader
* Expert *
 
Join Date: Jul 2003
Location: Camp Hill, PA
Posts: 1,992
Default

Quote:
Originally Posted by Deadalus
No, it isn't part of the signature...
Whoops; I don't why I said that. Must have been the goofballs.
Reply With Quote
  #15  
Old 09-25-2006, 06:20 AM
00100b's Avatar
00100bHiding base-class member in derived-class 00100b is offline
Martian In Disguise

Retired Moderator
* Guru *
 
Join Date: May 2003
Location: Minneapolis, MN
Posts: 9,566
Default

Quote:
Originally Posted by AFterlife
That makes no sense to me.If you don't want it accessed in a derived class why declare it as public?
I'll try to explain the actual reason for this approach below.
Quote:
Originally Posted by reboot
Maybe he didn't write/have access to the base class.
Thanks for the scape-goat, but this is all me.
Quote:
Originally Posted by shaul_ahuva
... Well, it's too long to actually quote but...
I wish I would have had time to review this information over the weekend. I've definitely got some more reading/playing to do. If what I am understanding at this point is correct, and that this is an IDE-behavior, then I may be able to procede as planned. Maybe.


Now, down to the reason why I thought about taking this approach.

EMBARC is a specification for the structure of electronic manifests for Rolls of Newsprint. Each row in an EMBARC file is 128-characters long (fixed). The first 8-characters break down into 4 different fields and is common in structure across all of the possible Record Types. The structure for the rest of the 120-characters are specific to the type of record indicated in two of those 4 fields.

The four "common" fields are:
  • Control Character - Position = 1, Length = 1
  • Record Type - Position = 2, Length = 1
  • Record Type Suffix - Position = 3, Length = 1
  • Sequence Number - Position = 4, Length = 5

The types of "records" are:
  • Transmission Header - Record Type = 1, Record Type Suffix = T
  • Transmission Record of Export - Record Type = 1, Record Type Suffix = E
  • Manifest Header - Record Type = 1, Record Type Suffix = M
  • Common Ship-To Information (1 of 3) - Record Type = 2, Record Type Suffix = A
  • Common Ship-To Information (2 of 3) - Record Type = 2, Record Type Suffix = B
  • Common Ship-To Information (3 of 3) - Record Type = 2, Record Type Suffix = C
  • Common Sold-To Information (1 of 3) - Record Type = 3, Record Type Suffix = A
  • Common Sold-To Information (2 of 3) - Record Type = 3, Record Type Suffix = B
  • Common Sold-To Information (3 of 3) - Record Type = 3, Record Type Suffix = C
  • Item Header - Record Type = 4, Record Type Suffix = M
  • Item Description - Record Type = 4, Record Type Suffix = D
  • Item Detail - Record Type = 5, Record Type Suffix = M
  • Supplemental Item Detail - Record Type = 5, Record Type Suffix = S
  • Item Summary - Record Type = 6, Record Type Suffix = M
  • Manifest Trailer - Record Type = 9, Record Type Suffix = M
  • Transmission Trailer - Record Type = 9, Record Type Suffix = T
A given transmission can contain 1 or more manifests.
A given manifest can contain 1 or more items (or Product Types).
A given item can contain 1 or more details (or individual rolls).

The actual break-down of each Record Type is a little long to post here.

Now, the parsing of the fields for each record type is the same, just different positions/lengths within the 120-characters that make up each record's data.

My thought was, to create a base-class that provided the interfaces that would be common to all record types, as well as, all of the possible fields for each record type. Then in a derived-class for each record type, hide those interfaces that weren't applicable. The code for parsing any record type would be written once, in the base-class. The only code that would need to be written in any of the derived-classes would be just the method-prototypes that hide (or mask out) the non-applicable members.

To me (and hence my idea for this approach), was that this implementation would provide a "self-polymorphic" component library that would be fed the contents of an EMBARC file and provide an hierarchical representation of the data that it contains.
__________________
The only stupid question is the one that goes un-asked.

Last edited by 00100b; 09-25-2006 at 06:28 AM.
Reply With Quote
  #16  
Old 09-25-2006, 06:43 PM
AFterlife's Avatar
AFterlife AFterlife is offline
Contributor
 
Join Date: Dec 2003
Location: Mi
Posts: 654
Default

Surprised I'm back here, mainly out of curiousity.That is pretty interesting.How many different types of records are there?Without burning to many brain cells...I have done some similar things.Maybe it's possible to create a similar base class that will contain all properties needed and hiding(private and if needed shadowing) the ones that aren't needed in derived classes.Then if you need to have polymorphic behavior to have all the methods of that class you could use a simple FOR EACH statement.(Assuming you know how to reference it)Anyways, hope that helps in some way shape or form.That's my 2 minute thought anyways...LOL!
__________________
"Real knowledge is to know the extent of ones ignorance"

Last edited by AFterlife; 09-25-2006 at 06:51 PM.
Reply With Quote
  #17  
Old 09-26-2006, 06:56 AM
00100b's Avatar
00100bHiding base-class member in derived-class 00100b is offline
Martian In Disguise

Retired Moderator
* Guru *
 
Join Date: May 2003
Location: Minneapolis, MN
Posts: 9,566
Default

Quote:
Originally Posted by AFterlife
...Maybe it's possible to create a similar base class that will contain all properties needed and hiding(private and if needed shadowing) the ones that aren't needed in derived classes....
Uh, yeah. Isn't that the topic of this thread and what I am trying to accomplish?
__________________
The only stupid question is the one that goes un-asked.
Reply With Quote
  #18  
Old 09-26-2006, 08:03 AM
shaul_ahuvaHiding base-class member in derived-class shaul_ahuva is offline
Ultimate Contributor

Retired Leader
* Expert *
 
Join Date: Jul 2003
Location: Camp Hill, PA
Posts: 1,992
Default

This approach seems to be attempting to force the interface to do what you want without really accomplishing anything. Even if you could successfully shadow the methods to "hide" them, any user could still just assign a variable of the base type to the returned object and call the base methods/properties directly. As we've seen, the compilers are helpful enough to automagically do this for you if the shadowed member is not accessible and the base member is.

I've been doing some thinking about other implementations, but I don't know if any of these would help or hinder:
  1. An associative class (a la JavaScript) using a default property taking a name as a parameter. The System.Management.ManagementObject and System.DirectoryServices.DirectoryEntry classes are similar to what I'm thinking of. If you're looking for strongly-typed access, obviously this isn't the cure.
  2. Don't shadow and keep only the truly common properties on the base class. Use derived classes and/or interfaces for the non-common properties. I did something similar to this while working with SQL Reporting Services - each report goes through the same web service the same way, so I created a base class providing the basic services and the properties in the derived classes simply get/set their values in a protected name/value collection. I guess it's ultimately a strongly-typed wrapper around #1.
  3. Implement a class factory.
Reply With Quote
  #19  
Old 09-26-2006, 10:13 AM
Rockoon's Avatar
Rockoon Rockoon is offline
Joseph Koss

* Guru *
 
Join Date: Aug 2003
Location: Unfashionable End
Posts: 3,615
Default

Is there any particular benefit to inheriting your base class other than the 'beauty' of it?

See, I'm no OO expert.. not by a long shot.. I still 'struggle' with tough questions such as "Should I use a singleton or a global?"

I guess I'm asking why a set of class wrappers isnt a suitable design decision here.
Reply With Quote
  #20  
Old 09-26-2006, 10:32 AM
00100b's Avatar
00100bHiding base-class member in derived-class 00100b is offline
Martian In Disguise

Retired Moderator
* Guru *
 
Join Date: May 2003
Location: Minneapolis, MN
Posts: 9,566
Default

Well, I'm no OO expert myself. In fact, I chose this "self-imposed" project in an attempt to study and learn the "inheritance" aspects of OOP.

My decision was based on the article "Visual Basic Concepts: When to Use Inheritance" which states, in part:
Quote:
Inheritance is a useful programming concept, but it is easy to use inappropriately. Often interfaces do the job better. This topic and When to Use Interfaces help you understand when each approach should be used.

Inheritance is a good choice when:
  • Your inheritance hierarchy represents an is-a relationship and not a has-a relationship.
  • You can reuse code from the base classes.
  • You need to apply the same class and methods to different data types.
  • The class hierarchy is reasonably shallow, and other developers are not likely to add many more levels.
  • You want to make global changes to derived classes by changing a base class.
These considerations are discussed in order below.
__________________
The only stupid question is the one that goes un-asked.
Reply With Quote
Reply


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off

Forum Jump

Advertisement:





Free Publications
The ASP.NET 2.0 Anthology
101 Essential Tips, Tricks & Hacks - Free 156 Page Preview. Learn the most practical features and best approaches for ASP.NET.
subscribe
Programmers Heaven C# School Book -Free 338 Page eBook
The Programmers Heaven C# School book covers the .NET framework and the C# language.
subscribe
Build Your Own ASP.NET 3.5 Web Site Using C# & VB, 3rd Edition - Free 219 Page Preview!
This comprehensive step-by-step guide will help get your database-driven ASP.NET web site up and running in no time..
subscribe
Hiding base-class member in derived-class
Hiding base-class member in derived-class
Hiding base-class member in derived-class Hiding base-class member in derived-class
Hiding base-class member in derived-class
Hiding base-class member in derived-class
Hiding base-class member in derived-class Hiding base-class member in derived-class Hiding base-class member in derived-class Hiding base-class member in derived-class Hiding base-class member in derived-class Hiding base-class member in derived-class Hiding base-class member in derived-class
Hiding base-class member in derived-class
Hiding base-class member in derived-class
 
Hiding base-class member in derived-class
Hiding base-class member in derived-class
 
-->