public class ClassType extends TypeTerm
A class implementation uses the information declared in its interface.
It is interpreted as follows: only non-method members - hereafter
called fields - correspond to actual slots in an object
structure that is an instance of the class and thus may be
updated. On the other hand, all members (i.e., both fields and
method members) are defined as global functions whose first
argument stands for the object itself (that must be explicitly
referred to as this everywhere).
Our prototype syntax for a class definition is of the form:
class <classname> { <interface> } [ { <implementation> } ]
For example, one can declare a class to represent a simple counter as follows:
class Counter
{
value : int = 1;
method set : int -> Counter;
}
{
set (n : int) : Counter = (this.value = n);
}
The first block specifies the interface for the class type
Counter defining two members: a field
value of type int and a
method set taking an argument of type
int and returning a
Counter object. It also specifies an initialization expression
(1) for the value
field. Specifying a field's initialization is optional - when missing, the field will be
initialized to a null value of appropriate type: 0 for
an int, 0.0 for a
real, false for a
boolean, _ for
void, and null(T)
for any other type T. [NB: Strictly speaking, a
field of type void is useless since it can only have
the unique value of this type (i.e., _). Thus, a
void field should arguably be disallowed. On the other
hand, allowing it is not semantically unsound and may be tolerated for the sake of
uniformity.]
The second (optional) block of a class declaration defines its implementation. Thus, the implementation block for the Counter class defines the body of the set method.
Note that a method's implementation can as well be given outside the
class declaration as a function whose first argument's type is the
class. For example, we could have defined the set method of the class Counter as:
def set (x : Counter, n : int) : Counter = (x.value = n);
On the other hand, although a field is also semantically a function
whose first argument's type is a class, it may not be defined
outside its class. Defining a declared field outside a class
declaration causes an error. This is because the code of a field is
always fixed and defined to return the value of an object's slot
corresponding to the field. Note however that one may define a unary
function whose argument is a class type outside this class when it is
not a declared field for this class. It will be understood as a
method for the class (even though it takes no extra argument
and may be invoked in "dot notation" without parentheses as a field
is) and thus act as a "static field" for the class. Of course field
updates using dot notation will not be allowed on these pseudo
fields. However, they (like any global variable) may be (re)set using
a global (re)definition at the top level, or a nested global
assignment.
Note also that a field may be functional without being a method - the essential difference being that a field is part of the structure of every object instance of a class and thus may be updated within an object instance, while a method is common to all instances of a class and may not be updated within a particular instance, but only globally for all the class' instances.
Thus, every time a Counter object
is created with new or
static, as in, for example:
c = new Counter;
the value 1 will be used to
initialize the slot that corresponds to the location of the
value field.
Then, field and method invocation can be done using the familiar
"dot notation"; e.g.:
c.set(c.value+2);
write(c.value);
This will set c's value field
to 3 and print out this value.
This code is exactly equivalent to:
set(c,value(c)+2);
write(value(c));
Indeed, field and method invocation simply amounts to functional application. This scheme offers the advantage that an object's fields and methods may be manipulated as functions (i.e., as first-class citizens) and no additional setup is needed for type-checking and/or type inference when it comes to objects.
Incidentally, some or all type information may be omitted while specifying
a class's implementation (though not its interface) as long
as non-ambiguous types may be inferred. Thus, the class
Counter above could be
defined simply as:
class Counter
{
value : int = 1;
method set : int -> Counter;
}
{
set (n) = (this.value = n);
}
Declaring a class type and defining its implementation causes the
following:
| Constructor and Description |
|---|
ClassType(Tables tables,
java.lang.String name) |
ClassType(Tables tables,
java.lang.String name,
java.util.AbstractList arguments) |
ClassType(Tables tables,
java.lang.String name,
Type[] arguments,
ClassInfo classInfo) |
| Modifier and Type | Method and Description |
|---|---|
void |
bindArguments() |
ClassInfo |
classInfo() |
ClassType |
declareMembers(java.util.AbstractList members,
java.util.AbstractList types,
java.util.AbstractList fieldInits,
java.util.AbstractList typeArguments)
Declares the members of this class type from the specified information and
returns this class type.
|
DefinedEntry[] |
fields() |
void |
initialize(ObjectInstance object,
Runtime init)
Initializes the fields of the specified object instance using the specified
Runtime.
|
int |
intFieldsCount() |
boolean |
isDeclared() |
byte |
kind()
This returns the value identifying what kind of type this is.
|
DefinedEntry[] |
methods() |
int |
nextOffset(byte sort)
Increments and returns the field offset in this class for the given sort.
|
int |
objectFieldsCount() |
int |
realFieldsCount() |
java.lang.String |
toFullString()
N.B.: The following definition specifies only the
default behavior for this method.
|
void |
unbindArguments() |
void |
undeclareClass(Tables tables) |
argument, arguments, arity, checkOccurrence, copy, eqCode, flatten, getParameters, instantiate, isEqualTo, isEqualTo, isPolymorphic, numberOfTypeComponents, setArguments, setArguments, setTypeRefComponent, toString, typeRefComponent, unify, unifyactualType, array, array, baseType, baseTypeRef, BOOLEAN, BOXED_BOOLEAN, BOXED_CHAR, BOXED_INT, BOXED_REAL, boxSort, CHAR, copy, curry, equals, findValue, getParameters, getValue, INT, is, isBag, isBoolean, isBoxedType, isChar, isCollection, isGlobalUnsafe, isInt, isList, isPrimitive, isReal, isSet, isString, isVoid, kindString, rank, REAL, resetNames, setBoxed, shadowType, sort, standardize, toQuantifiedString, toQuantifiedString, typeComponent, unwrapper, value, wrapperpublic ClassType(Tables tables, java.lang.String name, Type[] arguments, ClassInfo classInfo)
public ClassType(Tables tables, java.lang.String name)
public ClassType(Tables tables, java.lang.String name, java.util.AbstractList arguments)
public final byte kind()
Typepublic final ClassInfo classInfo()
public final boolean isDeclared()
public final DefinedEntry[] fields()
public final DefinedEntry[] methods()
public final int intFieldsCount()
public final int realFieldsCount()
public final int objectFieldsCount()
public final int nextOffset(byte sort)
public final void bindArguments()
public final void unbindArguments()
public final ClassType declareMembers(java.util.AbstractList members, java.util.AbstractList types, java.util.AbstractList fieldInits, java.util.AbstractList typeArguments) throws ClassDeclarationException
ClassDeclarationExceptionpublic final void undeclareClass(Tables tables)
public final void initialize(ObjectInstance object, Runtime init) throws ObjectInitializationException
ObjectInitializationExceptionpublic final java.lang.String toFullString()
TypeN.B.: The following definition specifies only the default behavior for this method. Specific subclasses are generally expected to override this method.
toFullString in class Type