Objective CAML

Contributed by Chris Rathman
Reworked by Pixel <pixel@mandrakesoft.com>

polymorph.ml

class virtual shape initx inity =
   object (self)
      val mutable x = initx
      val mutable y = inity

      (* accessors for x & y coordinates *)
      method getX = x
      method getY = y
      method setX newx = x <- newx
      method setY newy = y <- newy

      (* move the x & y position of the object *)
      method moveTo newx newy =
         self#setX newx;
         self#setY newy
      method rMoveTo deltax deltay =
         self#setX (self#getX + deltax);
         self#setY (self#getY + deltay)

      (* abstract draw method *)
      method virtual draw : unit
   end

class rectangle initx inity initwidth initheight =
   object (self)
      inherit shape initx inity
      val mutable width = initwidth
      val mutable height = initheight

      (* accessors for width & height *)
      method getWidth = width
      method getHeight = height
      method setWidth newwidth = width <- newwidth
      method setHeight newheight = height <- newheight

      (* draw the rectangle *)
      method draw =
         Printf.printf "Drawing a Rectangle at:(%d,%d), width %d, height %d\n"
            self#getX self#getY self#getWidth self#getHeight
   end

class circle initx inity initradius =
   object (self)
      inherit shape initx inity
      val mutable radius = initradius

      (* accessors for the radius *)
      method getRadius = radius
      method setRadius newradius = radius <- newradius

      (* draw the circle *)
      method draw =
         Printf.printf "Drawing a Circle at:(%d,%d), radius %d\n"
            self#getX self#getY self#getRadius
   end

let main () =
   (* set up lists to hold the shapes *)
   let (scribble: shape list) = [
      (new rectangle 10 20 5 6 :> shape);
      (new circle 15 25 8 :> shape)] in

      (* iterate through the lists and handle shapes polymorphically *)
      List.iter (fun each ->
         each#draw;
         each#rMoveTo 100 100;
         each#draw
      ) scribble;

      (* call a rectangle specific instance *)
      let arectangle = new rectangle 0 0 15 15 in
         arectangle#draw;
         arectangle#setWidth 30;
         arectangle#draw;;

main ();;

Compiling the code

ocamlc -c polymorph.ml
ocamlc -o polymorph.exe polymorph.cmo

Output

Drawing a Rectangle at:(10,20), width 5, height 6
Drawing a Rectangle at:(110,120), width 5, height 6
Drawing a Circle at:(15,25), radius 8
Drawing a Circle at:(115,125), radius 8
Drawing a Rectangle at:(0,0), width 15, height 15
Drawing a Rectangle at:(0,0), width 30, height 15

Chris Rathman / Chris.Rathman@tx.rr.com