This section uses the same example as for objects
(see Basic objects.fs Usage).
You can define a class for graphical objects like this:
object class graphical \ "object" is the parent class method draw ( x y -- ) class;
This code defines a class graphical
with an
operation draw
. We can perform the operation
draw
on any graphical
object, e.g.:
100 100 t-rex draw
where t-rex
is an object or object pointer, created with e.g.
graphical : t-rex
.
How do we create a graphical object? With the present definitions,
we cannot create a useful graphical object. The class
graphical
describes graphical objects in general, but not
any concrete graphical object type (C++ users would call it an
abstract class); e.g., there is no method for the selector
draw
in the class graphical
.
For concrete graphical objects, we define child classes of the
class graphical
, e.g.:
graphical class circle \ "graphical" is the parent class cell var circle-radius how: : draw ( x y -- ) circle-radius @ draw-circle ; : init ( n-radius -- ) circle-radius ! ; class;
Here we define a class circle
as a child of graphical
,
with a field circle-radius
; it defines new methods for the
selectors draw
and init
(init
is defined in
object
, the parent class of graphical
).
Now we can create a circle in the dictionary with:
50 circle : my-circle
:
invokes init
, thus initializing the field
circle-radius
with 50. We can draw this new circle at (100,100)
with:
100 100 my-circle draw
Note: You can only invoke a selector if the receiving object belongs to
the class where the selector was defined or one of its descendents;
e.g., you can invoke draw
only for objects belonging to
graphical
or its descendents (e.g., circle
). The scoping
mechanism will check if you try to invoke a selector that is not
defined in this class hierarchy, so you’ll get an error at compilation
time.