Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

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:

PageCovers
Virtual methodsletting the object, not the variable, choose the method
Overridingoverride, and when an override can be overridden again
Abstract methodsmethods every derived type must supply
Calling the basebase( ... ) and base.Method( )
Runtime type checksis
Interfacesinterface, implements and class: a contract any type can take on
Several interfacesone type, many contracts; renamed and private mappings; trycast
Virtual destructorsdeleting through a base pointer
Slicingwhat passing by value does to a derived object

Activities

  1. Add a Truck that extends Vehicle with a load field and a constructor passing 6 to base( ... ), and pass one to Report.
  2. Print offsetof( Truck, load ) and explain the number.