Inheritance
When one type is a more specific kind of another, a bicycle being a kind of
vehicle, extends lets it start as the general type and add to it. The
derived type gets every field and method of its base without repeating them,
and it can be handed to any code written for the base.
type Vehicle
declare constructor( byval wheels as int32 = 4 )
declare function Describe( ) as ustring
wheels as int32
speed as int32
end type
constructor Vehicle( byval wheels as int32 )
this.wheels = wheels
end constructor
function Vehicle.Describe( ) as ustring
return wheels & " wheels at " & speed & " km/h"
end function
'' A Bicycle is a Vehicle with more fields.
type Bicycle extends Vehicle
declare constructor( byval gears as int32 )
gears as int32
end type
constructor Bicycle( byval gears as int32 )
base( 2 ) '' build the Vehicle part first
this.gears = gears
end constructor
'' Anything written for a Vehicle accepts a Bicycle.
sub Report( byref v as Vehicle )
print " "; v.Describe( )
end sub
dim as Bicycle bike = Bicycle( 21 )
bike.speed = 25 '' a field it inherited
print "bike has"; bike.gears; " gears"
Report( bike )
dim as Vehicle car
car.speed = 90
Report( car )
'' The base's fields come first, laid out exactly as in a Vehicle.
print "sizes:"; sizeof( Vehicle ); sizeof( Bicycle )
print "offsets:"; offsetof( Bicycle, wheels ); offsetof( Bicycle, speed ); _
offsetof( Bicycle, gears )
Output
bike has 21 gears
2 wheels at 25 km/h
4 wheels at 90 km/h
sizes: 8 12
offsets: 0 4 8
type Bicycle extends Vehicle makes Bicycle a Vehicle with one more
field. bike.speed and bike.Describe( ) work although Bicycle declares
neither; they are inherited.
The base part is built first. base( 2 ), the first statement of the
Bicycle constructor, chooses which Vehicle constructor builds the
Vehicle part and with what. Leave it out and the base's default constructor
runs instead. Calling the base covers this further.
The layout is the base's, then the new fields. The offsets show
wheels and speed exactly where they are in a Vehicle, with gears
after them. A Bicycle starts with a complete Vehicle, which is why
Report, written for a Vehicle, accepts bike as it is.
A type extends exactly one base. To be several things at once, it implements interfaces instead: any number of them, beside its one base.
The pages in this section:
| Page | Covers |
|---|---|
| Virtual methods | letting the object, not the variable, choose the method |
| Overriding | override, and when an override can be overridden again |
| Abstract methods | methods every derived type must supply |
| Calling the base | base( ... ) and base.Method( ) |
| Runtime type checks | is |
| Interfaces | interface, implements and class: a contract any type can take on |
| Several interfaces | one type, many contracts; renamed and private mappings; trycast |
| Virtual destructors | deleting through a base pointer |
| Slicing | what passing by value does to a derived object |
Activities
- Add a
Truckthat extendsVehiclewith aloadfield and a constructor passing 6 tobase( ... ), and pass one toReport. - Print
offsetof( Truck, load )and explain the number.