A slot description has the form
Visibility SlotName:SlotType = InitialValue
where Visibility and ‘= InitialValue’ are optional. Each slot of a class must have a distinct name, given by the atom SlotName. The Visibility, SlotType and InitialValue parts of the slot description are described separately.
A slot's visibility is either private, protected, or public. If its visibility is not specified, the slot is private. The following example shows all four possibilities:
:- class example = [w:integer, private x:integer, protected y:integer, public z:integer]
Slot z
is public, y
is protected, and both x
and w
are
private.
Direct access to private slots is strictly limited to the methods of the class. Any other access to such slots must be accomplished through these methods. Making slots private will allow you later to change how you represent your class, adding and removing slots, without having to change any code that uses your class. You need only modify the methods of the class to accomodate that change. This is known as information hiding.
Protected slots are much like private slots, except that they can also be directly accessed by subclasses. This means that if you wish to modify the representation of your class, you will need to examine not only the class itself, but also its subclasses.
Public slots, in contrast, can be accessed from anywhere. This is
accomplished through automatically generated get and put methods named
for the slot and taking one argument. In the example above, our
example
class would automatically support a get and put method
named z/1
. Note, however, that unlike other object oriented
programming languages that support them, public slots in SICStus
Objects do not violate information hiding. This is because you may
easily replace a public slot with your own get and put methods of the
same name. In this sense, a public slot is really only a protected
slot with automatically generated methods to fetch and store its
contents.
Within a method clause, any of the class's slots can be accessed via
the fetch_slot/2
and store_slot/2
predicates. These are the
only way to access private and protected slots. They may be used to
define get and put methods for the class, which provide controlled
access to the protected slots. But, they can only be used within the
method clauses for the class, and they can only refer to slots of the
current class and protected and public slots of superclasses.
In the slot description, public
, protected
and private
are
used as prefix operators. The obj_decl
module redefines the prefix
operator public
, as follows:
:- op(600, fy, [public]).
Unless you use the obsolete public/1
directive in your Prolog
programs, this should cause no problems.
A slot's type restricts the kinds of values it may contain. The slot
is specified in the slot description by one of the following Prolog
terms with the corresponding meaning. Most of these will be
familiar, but the last four, address
, term
, Class and
pointer(
Type)
, require some additional explanation:
integer
integer_32
integer_16
integer_8
unsigned
unsigned_32
unsigned_16
unsigned_8
float
float_32
atom
address
address
type is intended for use with foreign code.
A slot of this type might store an address returned from
a foreign function. That address might, in turn, be used
in calling another foreign function. Hence, most Prolog programmers can
safely ignore this type.
term
term
type is for general Prolog terms. Such a slot
can hold any of the other types. However, if you know
a slot will be used to hold only values of a particular
type, it is more efficient to specify that type in the class
definition.
Storing a term containing free variables is similar to
asserting a clause containing free variables into the
Prolog database. The free variables in the term are replaced
with new variables in the stored copy. And, when you
fetch the term from the slot, you are really fetching a
copy of the term, again with new variables.
null
object.
pointer(
Type)
address
type, except that access to this slot
yields, and update to this slot expects, a term of arity 1 whose
functor is Type and whose argument is the address. Again, most Prolog
programmers can safely ignore this type.
A slot description may optionally specify an initial value for the slot. The initial value is the value of the slot in every instance of the class, when the object is first created. The initial value must be a constant of the correct type for the slot.
If an initial value is not specified, a slot is initialized to a value
that depends on its type. All numbers are initialized to 0, of the
appropriate type. Atom and term slots are initialized to the
empty atom
(''
). Addresses and pointers are initialized to null pointers. And,
objects are initialized to the null
object.
More complicated initialization—not the same constant for every instance of the class—must be performed by create methods, which are described later.
null
objectThe null
object is a special object that is not an instance of any
class, but that can be stored in a slot intended for any class of
object. This is very much like the NULL
pointer in C. This is
useful when you do not yet have an object to store in a particular
slot.
In Prolog, the null
is represented by the atom null
.
Note that because the null
object is not really an object of any
class, you cannot determine its class with class_of/2
. Unless
noted otherwise, when we write of an object in this document, we
do not include the null
object.