Contributed by Chris Rathman
INTERFACE Shape; TYPE T <: Public; Public = ROOT OBJECT METHODS draw(); moveTo(newx: INTEGER; newy: INTEGER); rMoveTo(deltax: INTEGER; deltay: INTEGER); getX(): INTEGER; getY(): INTEGER; END; END Shape. |
MODULE Shape; REVEAL T = Public BRANDED OBJECT x: INTEGER; y: INTEGER; METHODS setX(newx: INTEGER) := SetX; setY(newy: INTEGER) := SetY; OVERRIDES moveTo := MoveTo; rMoveTo := RMoveTo; getX := GetX; getY := GetY; END; (* accessors for x & y *) PROCEDURE GetX(self: T): INTEGER = BEGIN RETURN self.x; END GetX; PROCEDURE GetY(self: T): INTEGER = BEGIN RETURN self.y; END GetY; PROCEDURE SetX(self: T; newx: INTEGER) = BEGIN self.x := newx; END SetX; PROCEDURE SetY(self: T; newy: INTEGER) = BEGIN self.y := newy; END SetY; (* move the shape position *) PROCEDURE MoveTo(self: T; newx: INTEGER; newy: INTEGER) = BEGIN self.setX(newx); self.setY(newy); END MoveTo; PROCEDURE RMoveTo(self: T; deltax: INTEGER; deltay: INTEGER) = BEGIN self.moveTo(self.getX() + deltax, self.getY() + deltay); END RMoveTo; BEGIN END Shape. |
INTERFACE Rectangle; IMPORT Shape; TYPE T <: Public; Public = Shape.T OBJECT METHODS init(x: INTEGER; y: INTEGER; width: INTEGER; height: INTEGER): T; getWidth(): INTEGER; getHeight(): INTEGER; setWidth(newwidth: INTEGER); setHeight(newheight: INTEGER); END; END Rectangle. |
MODULE Rectangle; IMPORT IO; IMPORT Fmt; REVEAL T = Public BRANDED OBJECT width: INTEGER; height: INTEGER; OVERRIDES init := Init; getWidth := GetWidth; getHeight := GetHeight; setWidth := SetWidth; setHeight := SetHeight; draw := Draw; END; (* Initialize the attributes of the object *) PROCEDURE Init(self: T; x: INTEGER; y: INTEGER; width: INTEGER; height: INTEGER): T = BEGIN self.moveTo(x, y); self.setWidth(width); self.setHeight(height); RETURN self; END Init; (* accessors for width & height *) PROCEDURE GetWidth(self: T): INTEGER = BEGIN RETURN self.width; END GetWidth; PROCEDURE GetHeight(self: T): INTEGER = BEGIN RETURN self.height; END GetHeight; PROCEDURE SetWidth(self: T; newwidth: INTEGER) = BEGIN self.width := newwidth; END SetWidth; PROCEDURE SetHeight(self: T; newheight: INTEGER) = BEGIN self.height := newheight; END SetHeight; (* draw the rectangle *) PROCEDURE Draw(self: T) = BEGIN IO.Put("Drawing a Rectangle at:(" & Fmt.Int(self.getX()) & "," & Fmt.Int(self.getY()) & "), width " & Fmt.Int(self.getWidth()) & ", height " & Fmt.Int(self.getHeight()) & "\n"); END Draw; BEGIN END Rectangle. |
INTERFACE Circle; IMPORT Shape; TYPE T <: Public; Public = Shape.T OBJECT METHODS init(x: INTEGER; y: INTEGER; radius: INTEGER): T; getRadius(): INTEGER; setRadius(newradius: INTEGER); END; END Circle. |
MODULE Circle; IMPORT IO; IMPORT Fmt; REVEAL T = Public BRANDED OBJECT radius: INTEGER; OVERRIDES init := Init; getRadius := GetRadius; setRadius := SetRadius; draw := Draw; END; (* Initialize the attributes of the object *) PROCEDURE Init(self: T; x: INTEGER; y: INTEGER; radius: INTEGER): T = BEGIN self.moveTo(x, y); self.setRadius(radius); RETURN self; END Init; (* accessors for radius *) PROCEDURE GetRadius(self: T): INTEGER = BEGIN RETURN self.radius; END GetRadius; PROCEDURE SetRadius(self: T; newradius: INTEGER) = BEGIN self.radius := newradius; END SetRadius; (* draw the circle *) PROCEDURE Draw(self: T) = BEGIN IO.Put("Drawing a Circle at:(" & Fmt.Int(self.getX()) & "," & Fmt.Int(self.getY()) & "), radius " & Fmt.Int(self.getRadius()) & "\n"); END Draw; BEGIN END Circle. |
MODULE Main EXPORTS Main; IMPORT Shape; IMPORT Rectangle; IMPORT Circle; VAR scribble: ARRAY[1..2] OF Shape.T; rect : Rectangle.T; BEGIN (* set up some shape instances *) scribble[1] := NEW(Rectangle.T).init(10, 20, 5, 6); scribble[2] := NEW(Circle.T).init(15, 25, 8); (* iterate through some shapes and handle polymorphically *) FOR i := 1 TO 2 DO scribble[i].draw(); scribble[i].rMoveTo(100, 100); scribble[i].draw(); END; (* access a rectangle specific function *) rect := NEW(Rectangle.T).init(0, 0, 15, 15); rect.setWidth(30); rect.draw(); END Main. |
% Makefile for Modula-3 Shape polymorphism program import("libm3") module("Shape") module("Rectangle") module("Circle") implementation(Main) program(Main) |
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 30, height 15 |