User Tools

Site Tools


Object Orientated programming

by Richard Russell, April 2011

BBC BASIC isn't an Object Oriented (OO) language, but the CLASSLIB library (see Libraries) supports some of the more important features of that programming paradigm. To be specific, it provides the ability to create classes from which objects can be instantiated and from which subclasses can be inherited. It also allows classes to be contained within other classes (version 0.90 or later only).

A class is rather like a structure, except that as well as encapsulating several data items (members) it also encapsulates the functions used to operate on those items (methods). Hence the data and the functions associated with those data are tightly bound together (see this Wikipedia article).

Here is a very simple example of how classes and objects can be used. Suppose we wish to create a class which describes an ellipse: the class will need to incorporate members which describe the size of the ellipse (specifically its semi-minor and semi-major axes) and methods to set the size and return information about the ellipse. The first step is to declare a conventional BBC BASIC structure containing the members and methods:

        DIM Ellipse{a, b, _set_size, _get_area}

Here a and b are the members (representing the lengths of the semi-minor and semi-major axes respectively) and _set_size and _get_area are the methods (used to set the size of the ellipse and return its area respectively). You may wish to choose a naming convention to make it clear which are the members and which are the methods, but CLASSLIB does not require this.

We now define the methods, using a variant of the regular DEF statement (note the absence of the PROC or FN keywords, and the space before the parameters):

        DEF Ellipse._set_size (a,b) Ellipse.a = a : Ellipse.b = b : ENDPROC
        DEF Ellipse._get_area = PI * Ellipse.a * Ellipse.b

We could also have specified a constructor (a method which is called automatically when the object is created) and/or a destructor (called when the object is discarded) but for simplicity this example doesn't use either.

As with DEF PROC and DEF FN single line definitions can be placed anywhere in the program, but multi line definitions must be placed where they won't be accidentally executed (normally at the end of the program, after the END statement).

Having created the structure and defined its methods we now register it as a class:


Now the class Ellipse is fully defined. Before we can use it, we must instantiate one or more objects (instances of the class), for example:

        PROC_new(myellipse{}, Ellipse{}) 

Having created the object myellipse we can perform operations on it:

        PROC(myellipse._set_size)(10.0, 20.0)
        PRINT "Area of ellipse is "; FN(myellipse._get_area)

Finally when we've finished with the object we release the memory it occupied:


Another feature provided by most Object Orientated languages is inheritance. This allows a subclass to inherit the members and methods from a parent class. Suppose we now want to create a class for a circle. We could start from scratch, but a circle is a special case of an ellipse so instead we can create a Circle class which inherits from the Ellipse class:

        DIM Circle{_get_circumference}
        PROC_inherit(Circle{}, Ellipse{})

The class inherits the _get_area method from its parent, but the Circle class has an extra _get_circumference method. For convenience we can also override the inherited _set_size method with a new version which takes only one parameter (the radius):

        DEF Circle._get_circumference = 2 * PI * Circle.a
        DEF Circle._set_size (r) Circle.a = r : Circle.b = r : ENDPROC 

Now we can use the derived Circle class:

        PROC_new(mycircle{}, Circle{})
        PRINT "Area is "; FN(mycircle._get_area)
        PRINT "Circumference is "; FN(mycircle._get_circumference)

Here mycircle._set_size is the overridden method, mycircle._get_area is the method in the parent Ellipse class, and mycircle._get_circumference is the additional method in the Circle subclass.

It is possible to create a subclass of Circle, thus creating a hierarchy of classes. Suppose we want to represent a circle in 2D space, which will therefore require additional data representing its position and an additional method to set the position:

        DIM CircleXY{x, y, _set_position}
        PROC_inherit(CircleXY{}, Circle{})
        DEF CircleXY._set_position (x,y) CircleXY.x = x : CircleXY.y = y : ENDPROC

Now we have an EllipseCircleCircleXY class hierarchy.

Class inheritance is appropriate when two classes have an 'is a' relationship; for example the circle and the ellipse. An alternative relationship between classes is 'has a', in which case containment is appropriate. For example the class Bicycle could contain two instances of the class Wheel. This is supported in CLASSLIB (version 0.90 or later) using the following syntax:

        INSTALL @lib$+"CLASSLIB"
        DIM Wheel{diameter, _set_diameter, _get_diameter, _get_circumference}
        DEF Wheel._set_diameter (diam) Wheel.diameter = diam : ENDPROC
        DEF Wheel._get_diameter = Wheel.diameter
        DEF Wheel._get_circumference = PI * Wheel.diameter
        DIM Bicycle{frontwheel{}=Wheel{}, rearwheel{}=Wheel{}, @bicycle}
        DEF Bicycle.@bicycle Bicycle.frontwheel.diameter = 25 : ENDPROC
        PROC_new(mybike{}, Bicycle{})
        PRINT FN(mybike.frontwheel._get_circumference)
        PROC(mybike.frontwheel._set_diameter) (26.5)
        PROC(mybike.rearwheel._set_diameter) (27.0)
        PRINT FN(mybike.frontwheel._get_circumference)
        PRINT FN(mybike.rearwheel._get_circumference)

Here Bicycle is the container class; it can have its own members and methods. In the above example it has a constructor, indicated by a method name starting with @.

This website uses cookies for visitor traffic analysis. By using the website, you agree with storing the cookies on your computer.More information
object_20orientated_20programming.txt · Last modified: 2018/04/17 18:52 by tbest3112