Misunderstanding Inheritance?

  • Thread starter Thread starter Pat Kelly via .NET 247
  • Start date Start date
P

Pat Kelly via .NET 247

I have the following code that will not compile. It gives'A.Protected Sub SomeMethod()' is not accessible in this contextbecause it is 'Protected'. Class B can call the inherited method(SomeMethod) on itself just fine but not on a different instanceof Class A or Class B.


Public Class A

Protected Sub SomeMethod()
End Sub

Protected Sub SomeOtherMethod(ByVal objA As A)
objA.SomeMethod() 'No compile error - instance of A can callmethod on other instance
End Sub

End Class

Public Class B
Inherits A

Protected Sub AnotherMethod(ByVal objA As A)
objA.SomeMethod() 'Compile error
End Sub

Protected Sub YetAnotherMethod(ByVal objB As B)
objB.SomeMethod() 'No Compile error
End Sub



End Class

MSDN says protected methods are only accessible from within theirown class or a derived class, but do not mention anything aboutbeing accessible only to the current instance. I am also puzzledby the inconsistency between the way the base class and thederived class handle calls to another instance. A can call aprotected method on another instance of A, B can call theinherited method on another instance of B, but B cannot call theinherited method on an instance of A. Can anyone explain this?
 
Hi Pat,

"Protected" Members are only available within in the class as well as
derived classes. For example

Public Class A

Private sub SomePrivateMethod()
This method is hidden to everyone except this class!
End Sub

Public sub SomePublicMethod()
This method is visible to everyone!
End Sub

Protected Sub SomeProtectedMethod()
This method is only visible to this class and derived classes!
End Sub

Public shared Sub PublicSharedMethod()
This method is visible to everyone and you do not need to make an
explicit declaration in order to use it!
i.e. You can call "A.PublicSharedMethod()" and it will do it's "stuff"
End Sub

End Class


Public Class B
Inherits A

Public Sub DoPrivateStuff()
Call MyBase.SomePrivateMethod() << NOT POSSIBLE!
End Sub

Public Sub DoPublicStuff()
Call MyBase.SomePublicMethod()
End Sub

Public Sub DoProtectedStuff()
Call MyBase.SomeProtectedMethod()
End Sub

Protected Sub DoSharedStuff()
Call A.PublicSharedMethod()
End Sub

End Class

I'm not quite sure what you are trying to do exactly, but it looks like you
may as well just use Public methods. Unfortunately VB.NET does not include
as many access modifiers as C#; which contains "Internal" which means that
it's only accessible within that particular assembly. I hope this helps.

Nick.
 
Unfortunately VB.NET does not include
as many access modifiers as C#; which contains "Internal" which means that
it's only accessible within that particular assembly. I hope this helps.

Isn't "Friend" equiv to C#'s "internal"?

Greg
 
I have the following code that will not compile. It gives 'A.Protected Sub SomeMethod()' is not accessible in this context because it is 'Protected'. Class B can call the inherited method (SomeMethod) on itself just fine but not on a different instance of Class A or Class B.
Public Class A

Protected Sub SomeMethod()
End Sub

Protected Sub SomeOtherMethod(ByVal objA As A)
objA.SomeMethod() 'No compile error - instance of A can call method on other instance
End Sub

End Class

Public Class B
Inherits A

Protected Sub AnotherMethod(ByVal objA As A)
objA.SomeMethod() 'Compile error
End Sub

Protected Sub YetAnotherMethod(ByVal objB As B)
objB.SomeMethod() 'No Compile error
End Sub

End Class

MSDN says protected methods are only accessible from within their own
class or a derived class, but do not mention anything about being
accessible only to the current instance. I am also puzzled by the
inconsistency between the way the base class and the derived class
handle calls to another instance. A can call a protected method on
another instance of A, B can call the inherited method on another
instance of B, but B cannot call the inherited method on an instance
of A. Can anyone explain this?

My favorite is that you can do this

Protected Sub(ByVal objA As A)
DirectCast(ObjA, B).SomeMethod() ' is OK if objA is really a B
objA.SomeMethod() ' but this won't compile
End Sub

You seem to understand the "what" of what's going on here, and seem to
be asking about the "why".

For that, I'd say consider the alternatives. First, it's pretty useful
to allow access to the private member of other instances of the same
class. For one thing, it allows you to do things like Compare and Clone
in reasonable ways. For another, it allows the system to use the self
reference (Me/this) in ways identical to other references. For example,

Dim newB as B = Me
newB.ProtectedMethod() ' Should this work???

But there's no similar advantage to allowing access to members of the
base class on other instances, and it creates some huge encapsulation
problems if you do it. Consider that pretty much every Forms component
derives from Control. If we don't restrict access to the base class,
then every component on a form could access the protected Control
methods of every other component on a form. And there's absolutely no
good reason to allow, say, a Label to call InvokeOnClick on a Button.

In any kind of complicated hierarchy, encapsulation would just fall
apart. If I can call objA.SomeMethod() above, then I can call
obj.Finalize() on anything in the system.

All in all, it may seem a bit strange, but I'd say .Net made the
absolutely correct decision here.
 
Hi there,
Isn't "Friend" equiv to C#'s "internal"?

I believe there is some difference as I recall a previous thread in here on
the subject. Though I may be getting mixed up with another access
modifier...

Nick.
 
Back
Top