Inheritance Question

T

tshad

I am playing with Inheritance and want to make sure I understand it.

I have the following Classes:
*******************************************
Public Class AuthHeader:Inherits SoapHeader
Public AuthHeaderName As String
Public SessionKey As String = "Default"
End Class

Public Class ServiceTicket:Inherits AuthHeader
Public IsAuthenticated As Boolean
Public SessionKey As String = "Default from ServiceTicket"
Public Expiration As DateTime
End Class

Public Class TempClass1:Inherits ServiceTicket
Public TomsClass1Name As String
End Class
*****************************************

I assume that inheritance depends on the order of definition.

Here SessionKey is being defined in 2 classes. For TempClass1 and
ServiceTicket, Session would be "Default from ServiceTicket" since it would
have been defined second. So if I create TempClass1, it would work
something like, SessionKey would first be "Default" but then ServiceTicket
would re-define it, since it inherited it (and is higher up the chain) and
change it to "Default from ServiceTicket".

In this case, if I had:

Dim objTempClass1 As new TempClass1
Dim objServiceTicket As new ServiceTicket
Dim objAuthHeader As new AuthHeader

objTempClass1.SessionKey = "Default from ServiceTicket" '
Inherited from ServiceKey
objServiceKey.SessionKey = "Default from ServiceTicket"
objAuthHeader.SessionKey = "Default"

But if I took out the Sessionkey from the ServiceKey class that it would be:

objTempClass1.SessionKey = "Default" ' Inherited from
AuthHeader
objServiceKey.SessionKey = "Default" ' Inherited
from AuthHeader
objAuthHeader.SessionKey = "Default"

Also, I originally got this from a sample program that didn't set the
defaults, but had it defined as:
*******************************************
Public Class AuthHeader:Inherits SoapHeader
Public AuthHeaderName As String
Public SessionKey As String
End Class

Public Class ServiceTicket:Inherits AuthHeader
Public IsAuthenticated As Boolean
Public SessionKey As String
Public Expiration As DateTime
End Class

Public Class TempClass1:Inherits ServiceTicket
Public TomsClass1Name As String
End Class
*****************************************

Is there any good reason to defining SessionKey again ServiceTicket?

I assume since it always would inherit from AuthHeader, it would always get
SessionKey from the inheritance. If it wanted to set SessionKey in
ServiceTicket, it could just set it by:

SessionKey = "Default"

without needing to redefine it.

Is this correct?

Thanks,

Tom
 
K

Karl Seguin [MVP]

First, you shouldn't have public fields...but I'll assume you were only
using them for illustrative purposes

Your code will generate warnings, and it's a good idea to fix those
warnings, especially as they pertain directly to your questions.

It's bad practice to reuse the names like you are doing. If you want to do
it, you should declare the SessionKey field in ServiceTicket as "shadows"
ala:

public shadows SessionKey as string

this means that the SessionKey in ServiceTicket is used instead of the onne
in AuthHeader for both ServiceTicket and TempClass1 - it's the same
behaviour as if you don't specify shadows, but it's more explicit and
removes the warning.

Also, if you use properties, you can mark the SessionKey property in the
base AuthHEader class as "overridable" which means child-classes can
implement the property as "overrides".

Now there is a difference between a property that shadows and one that
overrides. Take for example:

Public Class AuthHeader
Public Readonly overridable property SessionKey As String
get
return "DEFAULT"
end get
end property
End Class

Public Class ServiceTicket
Inherits AuthHeader

Public Readonly shadows property SessionKey As String
get
return "DEFAULT SESSION"
end get
end property
End Class

Public Class TempClass1
Inherits ServiceTicket

End Class


If we do:

dim temp as new TempClass1()
Console.WriteLine(temp.SessionKey)
Console.WRiteLine(ctype(temp, AuthHeader).SessionKey)

we'll get

DEFAULT SESSION
DEFAULT

as you can see, by using shadows and casting to the base type, the base type
is outputted.

If we run the same test but change the "shadows" to "overrides" we'll get
DEFAULT SESSION both times.

Karl
 
T

tshad

"Karl Seguin [MVP]" <karl REMOVE @ REMOVE openmymind REMOVEMETOO . ANDME
net> wrote in message news:[email protected]...
First, you shouldn't have public fields...but I'll assume you were only
using them for illustrative purposes

Yes.

I would normally use Properties or Protected.
Your code will generate warnings, and it's a good idea to fix those
warnings, especially as they pertain directly to your questions.

It's bad practice to reuse the names like you are doing. If you want to
do it, you should declare the SessionKey field in ServiceTicket as
"shadows"

That was one of my questions.

In this code, the SessionKey in the ServiceTicket is really irrelevant, is
it not?

I don't know why the example code was using it this way, since we would only
get one SessionKey. The only way I can think that this would be relevent
would be if the first SessionKey were set to some default value and you
wanted to override the value, but you could do that just as easily, as I
mentioned by just setting it.

I just wanted to see if I was missiong something.
ala:

public shadows SessionKey as string

Wouldn't this be the same as my question above? Why would I use that,
wouldn't there just be one variable?
this means that the SessionKey in ServiceTicket is used instead of the
onne in AuthHeader for both ServiceTicket and TempClass1 - it's the same
behaviour as if you don't specify shadows, but it's more explicit and
removes the warning.

Actually, I didn't get any warnings. I am using vbc to compile it. Maybe
that is different from using it in VB 2003.
Also, if you use properties, you can mark the SessionKey property in the
base AuthHEader class as "overridable" which means child-classes can
implement the property as "overrides".

Now there is a difference between a property that shadows and one that
overrides. Take for example:

Public Class AuthHeader
Public Readonly overridable property SessionKey As String
get
return "DEFAULT"
end get
end property
End Class

Public Class ServiceTicket
Inherits AuthHeader

Public Readonly shadows property SessionKey As String
get
return "DEFAULT SESSION"
end get
end property
End Class

Public Class TempClass1
Inherits ServiceTicket

End Class


If we do:

dim temp as new TempClass1()
Console.WriteLine(temp.SessionKey)
Console.WRiteLine(ctype(temp, AuthHeader).SessionKey)

we'll get

DEFAULT SESSION
DEFAULT

as you can see, by using shadows and casting to the base type, the base
type is outputted.

If we run the same test but change the "shadows" to "overrides" we'll get
DEFAULT SESSION both times.
So in my example (even though not properties), I assume I was doing an
"override" (which I also assume is the default) and you only have one
variable. With "shadows" I assume you have 2 variables. In my example,
could I have used Shadows in my Public statement and end up with 2 variables
that way?

I know it is not the best way, but just trying to get the theory down.

Thanks,

Tom
 
K

Karl Seguin [MVP]

WEll, sometimes you want to overwrite functionality in a base class. If you
control the base case, you'd mark the method as "overridable" and let sub
classes "overrides" it. A good example of this is the ToString() method
which is marked as "overridable" in the System.Object class, and which many
child classes "overrides".

The only time I've used shadows is when I don't control the base class (ie,
it's a library and I don't have the source) and I want to override
functionality. If that member isn't "overridable" then "shadows" is the only
way I can do it.

You seem to be implying that overriding/shadowing is irrelevant.I can't
agree with that. It's true that you probably won't use them often (shadows
less that overrides), but they are still useful tools to have. I find that I
write abstract members more, but that might just be me.

Karl

--
http://www.openmymind.net/



tshad said:
"Karl Seguin [MVP]" <karl REMOVE @ REMOVE openmymind REMOVEMETOO . ANDME
net> wrote in message news:[email protected]...
First, you shouldn't have public fields...but I'll assume you were only
using them for illustrative purposes

Yes.

I would normally use Properties or Protected.
Your code will generate warnings, and it's a good idea to fix those
warnings, especially as they pertain directly to your questions.

It's bad practice to reuse the names like you are doing. If you want to
do it, you should declare the SessionKey field in ServiceTicket as
"shadows"

That was one of my questions.

In this code, the SessionKey in the ServiceTicket is really irrelevant, is
it not?

I don't know why the example code was using it this way, since we would
only get one SessionKey. The only way I can think that this would be
relevent would be if the first SessionKey were set to some default value
and you wanted to override the value, but you could do that just as
easily, as I mentioned by just setting it.

I just wanted to see if I was missiong something.
ala:

public shadows SessionKey as string

Wouldn't this be the same as my question above? Why would I use that,
wouldn't there just be one variable?
this means that the SessionKey in ServiceTicket is used instead of the
onne in AuthHeader for both ServiceTicket and TempClass1 - it's the same
behaviour as if you don't specify shadows, but it's more explicit and
removes the warning.

Actually, I didn't get any warnings. I am using vbc to compile it. Maybe
that is different from using it in VB 2003.
Also, if you use properties, you can mark the SessionKey property in the
base AuthHEader class as "overridable" which means child-classes can
implement the property as "overrides".

Now there is a difference between a property that shadows and one that
overrides. Take for example:

Public Class AuthHeader
Public Readonly overridable property SessionKey As String
get
return "DEFAULT"
end get
end property
End Class

Public Class ServiceTicket
Inherits AuthHeader

Public Readonly shadows property SessionKey As String
get
return "DEFAULT SESSION"
end get
end property
End Class

Public Class TempClass1
Inherits ServiceTicket

End Class


If we do:

dim temp as new TempClass1()
Console.WriteLine(temp.SessionKey)
Console.WRiteLine(ctype(temp, AuthHeader).SessionKey)

we'll get

DEFAULT SESSION
DEFAULT

as you can see, by using shadows and casting to the base type, the base
type is outputted.

If we run the same test but change the "shadows" to "overrides" we'll get
DEFAULT SESSION both times.
So in my example (even though not properties), I assume I was doing an
"override" (which I also assume is the default) and you only have one
variable. With "shadows" I assume you have 2 variables. In my example,
could I have used Shadows in my Public statement and end up with 2
variables that way?

I know it is not the best way, but just trying to get the theory down.

Thanks,

Tom
 
T

tshad

I think you were misunderstanding what I was saying here.

I was not disagreeing with you on overrides were irrelevant. That wasn't
what I was asking. I know they are. I wasn't sure why I would use
shadowing until you explained how it was used.

In my example, I was trying to figure out why you would override SessionKey
in the case where there was no default value.

*******************************************
Public Class AuthHeader:Inherits SoapHeader
Public AuthHeaderName As String
Public SessionKey As String
End Class

Public Class ServiceTicket:Inherits AuthHeader
Public IsAuthenticated As Boolean
Public SessionKey As String
Public Expiration As DateTime
End Class

Public Class TempClass1:Inherits ServiceTicket
Public TomsClass1Name As String
End Class
*****************************************

Since SessionKey is not set to anything in AuthHeader and since SessionKey
will override it, why have it at all, as you will have access to the
variable since it is inherited? What do you gain (this case only)?

If it was:
*******************************************
Public Class AuthHeader:Inherits SoapHeader
Public AuthHeaderName As String
Public SessionKey As String = "some value"
End Class

Public Class ServiceTicket:Inherits AuthHeader
Public IsAuthenticated As Boolean
Public SessionKey As String
Public Expiration As DateTime
End Class

Public Class TempClass1:Inherits ServiceTicket
Public TomsClass1Name As String
End Class
*****************************************

Then I can see why you would do it. I just wanted to see if I was missing
anything.

On the question of using Shadowing a Base Class (library) where you don't
have the source, wouldn't that be kind of dangerous to Shadow a variable. I
assume you would only do that if you have documentation telling you how the
field is used. If it were not overridable, wouldn't that be because it
would cause some problem if you did?

One of the reasons I started doing this is because of the other post I did
about "Creating Generic Classes from 2 Classes", earlier today.

I have 2 classes that are exactly identical, except for a URL value. I
would be using it to allow me to use all the methods and properties from one
set of code. I tried just changing the URL, but that works for some of the
routines, but not all of them. I thought I could just set up a pointer that
pointer that pointed to one class of the other (setting it as an object) but
I had problem access the methods. So I thought maybe I could solve it
somehow using classes and overriding the methods or maybe as an interface
(haven't really looked at that yet).

So I am just playing with this to see if it would work before I start
redoing all the code.

Thanks,

Tom

"Karl Seguin [MVP]" <karl REMOVE @ REMOVE openmymind REMOVEMETOO . ANDME
net> wrote in message news:[email protected]...
 
K

Karl Seguin [MVP]

All variables have default values. But I agree there seems to be little
point of overriding something with the same value (null for now) up front.

Yes, shadowing can be risky, but sometimes necessary. It's particularly bad
when you get a code update which changes the mechanics of the base
implementation, which your code is now shadowing. Like overrides, you can
call the base implementation in shadows via mybase.SessionKey I believe
(again, not applicable to fields).

If I understand your problem, the best solution seems to be to implement a
base class, mark the property as overriable, and have 2 child classes
overrides the property to set their specific url.

Karl
 
T

tshad

"Karl Seguin [MVP]" <karl REMOVE @ REMOVE openmymind REMOVEMETOO . ANDME
net> wrote in message news:%[email protected]...
All variables have default values. But I agree there seems to be little
point of overriding something with the same value (null for now) up front.

Yes, shadowing can be risky, but sometimes necessary. It's particularly
bad when you get a code update which changes the mechanics of the base
implementation, which your code is now shadowing. Like overrides, you can
call the base implementation in shadows via mybase.SessionKey I believe
(again, not applicable to fields).

If I understand your problem, the best solution seems to be to implement a
base class, mark the property as overriable, and have 2 child classes
overrides the property to set their specific url.

Actually, I just want to set up multiple occurrences of a web service in my
code and just assign it to a generic object and use that object in the code.
Changing the URL doesn't work for all the web services. Someone said it
worked fine for him just changing the URL, and that is the case for some of
my web services, but not all. Instead of trying to make that work, I was
trying another way by adding a new web service for each server. But I can't
get that to work.

The problem is setting a base class and then setup these web services to
inherit the web services. I have no access to the source.

Thanks,

Tom
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top