Class inheritance, virtual functions

The POOL language supports class inheritance. You may define a base class, a general description of a group of turtle models, and derived classes which use the base class as a template for more specialized description of a particular model.

Derived classes have access to all member variables and functions of the base class.

Derived classes can use one, or multiple base classes, combining their functionalities together.

Derived classes can redefine member functions from the base class if the number of arguments remains unchanged. POOL functions are virtual: if some code in the base class contains calls to functions that are redefined in a derived class then a turtle always uses the function definition closest to its class up in the class hierarchy.

Turtle's constructor of a derived class first executes constructors of base classes, in the order in which they appear in the use instruction in the class definition. This order defines the final shape of the derived class with its member variables and functions.

Example 1:
Code illustrates the definition of a class derived from a base class, the order of constructors execution and availability of functions and variables in the derived class.

to base :x :y
  to get op :y end
  make "pub :x
  print "base

to derived :x :y
  use base :x :y
  to fn op :x + :y end
  print "derived

"t := (newt $derived 2 3) ;constructor of the derived class
print get @ :t    ;call to the base class member function
print fn @ :t     ;call to the derived class member function
print :pub @ :t   ;public variable from the base class
;print :x @ :t    ;error: :x is not available as public



Example 2:
Code illustrates virtual function application. The base class contains handling function onworldchanged that refreshes a plot of parametric curves. This function is called on each change of drawing settings. The function code contains call to a function prototype, draw. The actual implementation of this prototype is provided in derived classes. The structure of code allows for easy extension by other types of curves, which requires adding a short class with code specific to the new curve formula.

;base class: provides implementation of the
;functionality common to all derived classes
to curve :c
  to draw ;drawing function prototype:
  end     ; - implementation in derived classes

  ;handling function common to all classes, repaints
  ;the curve on changes in drawing settings
  to onworldchanged
    let "nx :pool_cfg,"scale_x
    let "ny :pool_cfg,"scale_y
    let "mx :pool_cfg,"center_x
    let "my :pool_cfg,"center_y
    if :sx <> :nx || :sy <> :ny || :cx <> :mx || :cy <> :my [
      (print :nx :ny :cx :cy)
      "sx := :nx "sy := :ny
      "cx := :mx "cy := :my
      draw     ; <--- call to the function prototype

  ;constructor stores initial settings: drawing
  ;scales and position of the screen center
  let "sx :pool_cfg,"scale_x
  let "sy :pool_cfg,"scale_y
  let "cx :pool_cfg,"center_x
  let "cy :pool_cfg,"center_y

  setpc :c ;setup color of the curve

;derived class: Lissajous curve
to lissajous :s :a :b :c
  use curve :c
  to draw
    pu setxy 0 :s pd
    repeat 361 [
      let "x :s * sin :a * repcount
      let "y :s * cos :b * repcount
      setxy :x :y

;derived class: "butterfly" curve
to butterfly :s :c
  use curve :c
  to draw
    pu setxy 0 :s * (m_exp - 2) pd
    for [t 0 3600] [
      let "f :s * ((exp cos :t) -
        2 * (cos 4 * :t) -
        power sin :t/12 5)

      let "x :f * sin :t
      let "y :f * cos :t
      setxy :x :y

;construction of the derived class instances:
"l := (newt $lissajous 150 7 9 50)
"e := (newt $butterfly 50 {80 0 30 40})
;initial drawing:
draw @ :l
draw @ :e

Drawing in the graphics window; on each change of drawing settings the new parameters are printed in the text output.

See also:

use - declaration of inheritance from a base class

Turtle - object
#, turtle - get a turtle

Function as a value
$, func - get function as a value

Table of Content