Casting a class to a subclass

Can I not cast a subclass to its superclass?

I have a subclass tp that has superclass cp. They differ only in that tp has a couple more properties. The code looks like this:

Dim cp As New Class
Dim tp As New SubClass

tp = SubClass(cp)

This gets an illegal casting error at runtime. I realize there are a number of other ways to accomplish this, but I would have thought this was possible, setting all of the properties of tp to cp, leaving the extra properties in the initial state.

CP is an instance of “class” (I assume you didn’t REALLY name it “class”)
TP is an instance of Subclass (whose Superclass is “class”)

What exactly are you attempting to do?

TP has all the properties and attributes of “CLASS” plus whatever the subclass added…
CP ONLY has the properties and attributes of “CLASS” and NOT what subclass added…

So yes, CP cannot be “cast” to TP this way

No, you cannot upcast. But then, you don’t need to. Simple assignment works up. Casting is required down. cp can refer to a SubClass object, but tp cannot refer to a Class object. You must check (using ISA) before you cast.

cp = tp

if cp IsA SubClass then
     tp = SubClass(cp)
endif

I am a bit of a beginner at this so please bear with me…

“Up” is going from class to subclass?

Dave, I hear what you are saying but don’t understand the logic. Going from subclass to class (at least in this instance) would lose information (the extra properties) which might be thought of as bad. Going from class to subclass gains information in the new properties. It therefore seems more appropriate to go from class to subclass - some properties would have no value but nothing is lost.

Tim, I tried assignment and got a compiler error. I’ll try again.

Edit: it allowed an assignment of the subclass instance to the class instance, but threw a type mismatch the other way around.

“Up” is Subclass to Class.

cp can hold a reference to a Class object or any subclass of Class.
tp can hold a reference to a SubClass object, but not a Class object.

Casting does not change the kind of object. There is no transformation going on. Casting tells the compiler, “hey, this object is actually a SubClass, even though it is currently being referred to by a Class variable.”

Use the ISA operator to test whether the object is really of the type that you want.

Put another way, when you assign a subclass object to a variable of type superclass, eg.,

cp = tp

you are saying, “treat this SubClass object as if it were a Class object.” There is no loss of information, you are simply temporarily ignoring some information.

There is no way for a SubClass variable to ever refer to a Class object, because that would require creating information. That can’t be done.

Subclass and Superclass are confusing terms…

Superclass is the class from which you are creating your NEW class (the one with extra methods or properties)
Subclass is the NEW class that inherits from the Superclass

OK, thanks - it is sinking in. Wish there were a little more explanation in the docs but I suppose this is well worn if you are already familiar with objects. When I was taught programming the keyword had to start in column 7 of your IBM card punch deck…:).

I created a constructor for the subclass that accepts the class properties and assigns them.

If you have 5 classes:

Vehicle (Superclass)
Plane (Subclass of Vehicle)
Train (Subclass of Vehicle)
Automobile (Subclass of Vehicle)
SportsCar (Subclass of Automobile)

Then your variables:

Dim v as Vehicle // Can be any, since they are all vehicles Dim a as Automobile // Can be an Automobile or SportsCar since both are Automobiles Dim s as SportsCar // Can only be a SportsCar
If variable ‘a’ is an instance of SportsCar, it can’t access properties of the SportsCar class (it can only access properties of the Automobile class, or it’s superclass ‘Vehicle’); you need to cast a SportsCar variable as Tim mentioned:

if a IsA SportsCar then s = SportsCar(a) end if

What would qualify ‘a’ as a SportsCar? It was dimensioned as an Automobile, but in your example returns true in the IsA method for SportsCar. Under what conditions would that occur? Under what conditions would it return False?

a = new Automobile
if a IsA SportsCar then
s = SportsCar(a)
end if

Not following. Why would ‘a IsA SportsCar’ return true? Presumably a SportsCar has many different characteristics. If it returns true just because SportsCar is a subclass of Automobile, then why bother to check? I assume all SportsCars are Automobiles, but not all Automobiles are Sportscars, so IsA must have some criterium for making its return decision.

Too much shorthand above.

dim a as Automobile
dim s as SportsCar

a = New SportsCar  // this is legal, because a can refer to either an Automobile or a SportsCar
if a isa SportsCar then
    s = SportsCar(a)   // this will work, because a is currently referring to an object of type SportsCar
end
if a isa Plane then
   // this will not be true, because the object in a is a SportsCar, not a Plane.
end

a = New Plane
if a isa Plane then
   // now it's true
end

[quote=302536:@Tim Hare]

a = New Plane if a isa Plane then // now it's true end [/quote]
no - now it wont compile because you cant assign a Plane to an Automobile :stuck_out_tongue:

Assuming
Vehicle (Superclass)
Plane (Subclass of Vehicle)
Train (Subclass of Vehicle)
Automobile (Subclass of Vehicle)
SportsCar (Subclass of Automobile)

Dim v as Vehicle // Can be any, since they are all vehicles
Dim a as Automobile // Can be an Automobile or SportsCar since both are Automobiles
Dim s as SportsCar // Can only be a SportsCar

s = new SportsCar
if s isa SportsCar then
   // this will be true because s can ONLY be a SportsCar
end if
if s isA Automobile then
   // this will be true
end if
if s isA Vehicle then
   // this will be true
end if

// so much for the simple ones
// this is legal because V can refer to ANY kind of Vehicle OR one of its subclasses
// because a plane ISA vehicle, and automobile isa vehicle, and a plane isa vehicle
v = new SportsCar

if v isa SportsCar then
   // this will be true
end if
if v isA Automobile then
   // this will be true
end if
if v isA Vehicle then
   // this will be true
end if

// ok more exotic
// this is legal because V can refer to ANY kind of Vehicle OR one of its subclasses
v = new Train
if v isa SportsCar then
   // this will NOT  be true v refers to a TRAIN instance which is NOT a sportscar
end if
if v isA Automobile then
   // this will NOT  be true v refers to a TRAIN instance which is NOT an automobile
end if
if v isA Vehicle then
   // this will be true
end if

oops, still too many shortcuts

[quote=302525:@Norman Palardy]a = new Automobile
if a IsA SportsCar then
s = SportsCar(a)
end if[/quote]
OK but in this example, will the IsA be true or not? Specifically:

[code]Dim a As New Automobile
Dim s As New SportsCar

If a IsA SportsCar Then
s = Sportsar(a)
End If
[/code]

Will s get assigned to a or not? a could be a SportsCar. But maybe not. How does it know?

[quote=302545:@Jon Fitch]OK but in this example, will the IsA be true or not? Specifically:

[code]Dim a As New Automobile
Dim s As New SportsCar

If a IsA SportsCar Then
s = Sportsar(a)
End If
[/code]

Will s get assigned to a or not? a could be a SportsCar. But maybe not. How does it know?[/quote]

In exactly this code a will never be a sportscar because you assign “new Automobile” to it
But I dont think thats exactly what you’re asking

Suppose this code is valid (i’m just writing it in the forum text editor so it may not be)

Dim a As Automobile
Dim s As SportsCar

dim as double = rnd()

if rndNumber() < .5 then
   a = new Automobile
elseif rndNumber() < .33333 then
   a = new SportsCar
end if

If a IsA SportsCar Then
     s = Sportsar(a)
End If

Now you cannot tell ahead of time what a will refer to
It could be an Automobile OR a SportsCar

and the code still will work and do the right thing because, at runtime, the TYPE of whatever A refers to is known
And it may be an automobile or a sportscar

Both ISA and casting is evaluated at Runtime, so whatever object the variable happens to be pointing to at the time is used to evaluate. Neither is done by the compiler.

[quote=302549:@Norman Palardy]In exactly this code a will never be a sportscar because you assign “new Automobile” to it
But I dont think thats exactly what you’re asking
[/quote]
That is pretty much what I am asking. If the program is unsure what it is dealing with, then IsA can test it. But there is no way that an Automobile instance that did not start as a SportsCar can be made into a SportsCar, without creating a SportsCar, taking the parts off the Automobile and bolting them on the SportsCar (e. g. assigning the appropriate property values) - correct?