Example 3-7. Examples:
class VIEWER{DATA < $VIEWER_DATA} is ... end; immutable class QUATERNION is ... end; external FORTRAN class BLAS is ... end; partial class MIXIN is ... end |
class ==> [ immutable | partial | external identifier ] class uppercase_identifier [ parameterization ] [ subtyping_clause ] is [ class_element ] { ; [ class_element ] } end |
There are three types that have implementations: reference, immutable, and external types. They are defined by classes beginning with 'class', 'immutable class', and 'external language class', respectively. Reference types may be aliased and usually are allocated on a dynamic heap. Immutable types (such as complex numbers) are immune to aliasing and usually do not require heap allocation. External types are used to allow Sather variables to refer to entities of other languages, and are discussed further on See Language Interface Extensions. Partial classes have no associated type and contain code that may only be included by other classes. Partial classes may not be instantiated: no routine calls from another class into a partial class are allowed, and no variables may be declared in another class of such a type.
Class names must be entirely uppercase (See Sather identifiers are used to name class features, method arguments, and local variables. Most consist of letters, decimal digits, and the underscore character, and begin with a letter. Iterator names additionally end with the '!' character. Abstract type names and class names are similar, but the letters must be uppercase and abstract type names begin with '$'. There are no restrictions on the lengths of Sather identifiers or class names. Identifiers, class names, and keywords must be followed by a character other than a letter, decimal digit, or underscore. This may force the use of white-space after an identifier.). The scope of class names is the entire program and two classes may have the same name only if they specify a different number of parameters (See Parameterization).
Subtyping clauses introduce edges into the type graph. Each type listed in the subtyping clause must be abstract. There is an edge in the type graph from each type in the list to the type being defined. Every type is automatically a subtype of $OB (See Built-in classes). A subtyping clause may not refer to 'SAME'. When a subtyping clause is used with a partial class, it does not introduce an edge into the type graph, but does enforce the basic subtyping rule (See The set of methods that may be called on a type is called the interface of that type. A type interface may not contain conflicting signatures. An interface I1 conforms to an interface I2 if for every method f2 in I2 there is a unique conforming method f1 in I1. The basic subtyping rule is: 'The interface of each type must conform to the interfaces of each of its supertypes.' This ensures that calls made on a type can be handled by any of its subtypes.) between the interface(s) of the abstract class(es) and the partial class. Only partial classes may have stubs (See Stubs).
Example 3-8. The complex number class from the standard library is a good example of a immutable class. 'CPX' is immutable because it is small and behaves with a mathematical semantics. Here we also see that complex numbers can be tested for equality with other objects ('$IS_EQ') and has a routine (str: STR) for conversion to a string ('$STR'). Note that the creation routine does not have to allocate new storage for the object - the object exists as soon as it is declared, with all its attributes set to void.
immutable class CPX < $IS_EQ, $STR is attr r,c:FLT; create(arg_r,arg_c:FLT): SAME is res:SAME; res := res.r(arg_r).c(arg_c); return res; end; is_eq(s: $OB): BOOL is ... end; str: STR is ... end; ... end; |
Example 3-9. The complex number class may also be coded as a reference class. Note that the creation routine must now allocate space for the object. Attribute values are then set within the created object, with a different syntax. All attributes are set within the newly created object; in the case of the immutable class, conceptually at least, changing an attribute results in a new object with the new attribute value.
class REF_CPX < $IS_EQ, $STR is attr r,c:FLT; create(arg_r,arg_c:FLT): SAME is res:SAME := new; res.r := arg_r; res.c := arg_c; return res; end; is_eq(s: $OB): BOOL is ... end; str: STR is ... end; ... end; |