Casting trouble

L

Larry Serflaten

I am trying to build a chart to help me track what gets called when
in the inheritance chain. I came across an error that has me puzzled.
I have a derived class that inherits from a base class, but when I declare
a variable of the derived type, I can't assign a base type to it.

I am puzzled because the derived type 'is a' base type, so why can't a
variable of the derived type be assigned a value of base type?

For brievity, here is the offending line (Strict on or off makes no
difference)

Dim parent As New Base
Dim daughter As Derived

daughter = parent ' Error : Cast not valid

Here are the actual Base and Derived classes:

Public Class Base
Public Sub AAA()
Console.WriteLine("Base:AAA")
End Sub
Public Sub BBB()
Console.WriteLine("Base:BBB")
End Sub
Public Overridable Sub CCC()
Console.WriteLine("Base:CCC")
End Sub
End Class

Public Class Derived
Inherits Base
Public Overloads Sub BBB()
Console.WriteLine("Derived:BBB")
End Sub
Public Overrides Sub CCC()
Console.WriteLine("Derived:CCC")
End Sub
Public Sub DDD()
Console.WriteLine("Derived:DDD")
End Sub
End Class

I have tried commenting everything out of the derived class except
the Inherits line, and it still did not work. Am I mistaken in thinking
that it should work?

LFS
 
I

Imran Koradia

Larry Serflaten said:
I am trying to build a chart to help me track what gets called when
in the inheritance chain. I came across an error that has me puzzled.
I have a derived class that inherits from a base class, but when I declare
a variable of the derived type, I can't assign a base type to it.

I am puzzled because the derived type 'is a' base type, so why can't a
variable of the derived type be assigned a value of base type?

For brievity, here is the offending line (Strict on or off makes no
difference)

Dim parent As New Base
Dim daughter As Derived

daughter = parent ' Error : Cast not valid

--- Thats because the variable 'parent' contains an instance of type 'Base'
while the variable 'daughter' is of type 'derived'.
The problem here is that 'an apple is always a fruit but a fruit is not
always an apple'. So when you are doing something like
parent = daughter its always going to work because the the derived class
always implements what the base class implements
by way of inheritance. But when you attempt to do the above, the compiler
cannot figure out how to attempt to fill in the
implementation that a derived class might have implemented from the base
class since the base class has none of that
information !

I think what you are trying to do is something like:
Dim parent as Base
parent = New Derived
Dim daughter as Derived
daughter = DirectCast(parent, Derived) 'assuming Option Strict On

Note the difference between this and what you were attempting - the parent
is of type Base but is instantiated to the type
Derived.

Remember that the reverse cast will always work - that is:
Dim parent as Base
Dim daughter as New Derived
parent = daughter 'this always works without cast even with Option Strict
On

hope this helps - that is if my explanation has not confused you :)

Imran.
 
T

Tom Shelton

I am trying to build a chart to help me track what gets called when
in the inheritance chain. I came across an error that has me puzzled.
I have a derived class that inherits from a base class, but when I declare
a variable of the derived type, I can't assign a base type to it.

I am puzzled because the derived type 'is a' base type, so why can't a
variable of the derived type be assigned a value of base type?

For brievity, here is the offending line (Strict on or off makes no
difference)

Dim parent As New Base
Dim daughter As Derived

daughter = parent ' Error : Cast not valid

Larry, this actually makes sense when you think about it... And there are
good technical reasons why this is the case (in fact, it is the case in
C++, C#, and Java as well). Think about it - if the compiler let you
assign a reference to a parent object to a daughter object what do you
think would happen when you tried to call DDD? The reference stored in
daughter would be a reference to a parent object that does not define DDD.
That would be big trouble :)


Here are the actual Base and Derived classes:

Public Class Base
Public Sub AAA()
Console.WriteLine("Base:AAA")
End Sub
Public Sub BBB()
Console.WriteLine("Base:BBB")
End Sub
Public Overridable Sub CCC()
Console.WriteLine("Base:CCC")
End Sub
End Class

Public Class Derived
Inherits Base
Public Overloads Sub BBB()
Console.WriteLine("Derived:BBB")
End Sub
Public Overrides Sub CCC()
Console.WriteLine("Derived:CCC")
End Sub
Public Sub DDD()
Console.WriteLine("Derived:DDD")
End Sub
End Class

I have tried commenting everything out of the derived class except
the Inherits line, and it still did not work. Am I mistaken in thinking
that it should work?

Yes. This can't work for the reasons above. Just think about what would
happen if the compiler allowed this and you wrote code like:

Dim parent As New Base
Dim daughter As Derived = parent

parent.DDD() ' blamo!

It is perfectly valid to go the other way: parent = daughter, since
daughter contains all of the implementation of parent.

HTH
 
L

Larry Serflaten

Larry Serflaten said:
I am puzzled because the derived type 'is a' base type, so why can't a
variable of the derived type be assigned a value of base type?

OK, Thanks Imran and Tom. I am actually running through all possible
combinations, just to verify which routines will be used:

Dim parent As New Base
Dim child As New Derived
Dim son As Base
Dim daughter As Derived

' Call all methods on parent
' Call all methods on child

son = parent
' Call all methods on son

son = child
' Call all methods on son

daughter = parent ' Error : Cast not valid
' Call all methods on daughter

daughter = child
' Call all methods on daughter


As you saw, I am not getting a full understanding of this inheritance,
especially as it pertains to Overrides, and Overloads, and the rest.
Hopefully if I can see it all laid out in a chart, I may then see a pattern
that will help to solidify how it all works....

LFS
 
P

Phill. W

As I understand it
- oh come on; don't laugh ;-)

Overloads - adds a "variation" of a routine that already exists in the
base class but that takes different argument(s), something like

[base]
Public Function Add( _
ByVal x as Long, _
, ByVal y as Long _
) as Long

[derived]
Public OverLoads Function Add( _
ByVal x as Long, _
, ParamArray y() as Long _
) as Long

Overrides - actively replaces a routine in the base class with an
alternative implementation for use in/by the derived class as in.

[base]
Public Overrideable Sub SetColours()
Me.BackColor = Color.White
End Sub

[derived]
Public Overrides Sub SetColours()
Me.BackColor = Color.Green
End Sub

HTH,
Phill W.
 
L

Larry Serflaten

Phill. W said:
Overloads - adds a "variation" of a routine that already exists in the
base class but that takes different argument(s), something like
Overrides - actively replaces a routine in the base class with an
alternative implementation for use in/by the derived class as in.

That seems to be the most of it, but there is also the quirky response
of using Me in the base class when it is used to call on some other
public member of the base class.

I am working on getting my facts straight, before I try to say how Me
responds in those cases....

LFS
 

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