class_element ==> const_definition | shared_definition | attr_definition | routine_definition | iter_definition | include_clause | stub |
The main body of each class is a semicolon separated list of elements which define the features of the class. The semantics of a class is independent of the textual order of its class elements. All features are named. Some features may contribute a reader and a writer routine of the same name to the class interface. The scope of feature names is the class body and is separate from the class namespace. If a feature is private, then it may only be referred to from within the class and is not part of the class interface.
There are language-specific restrictions on the elements that may appear in external classes (See Language Interface Extensions). Some names ('main' and 'invariant') are reserved for special purposes (See Special feature names).
Example 4-1. Examples:
const r:FLT:=45.6; private const a,b,c; private const d:=4,e,f |
const_definition ==> [ private ] const identifier ( : type_specifier := expression | [ := expression ] [ , identifier_list ] ) |
Constants are accessible by all objects in a class and may not be assigned to. If a type is specified, then the construct defines a single constant attribute named identifier and it must be initialized by the expression expression. This must be a constant expression which means that it is:
a character, boolean, string, integer or floating point literal expression (See Boolean literal expressions),
a void or void test expression (See void expressions),
an and or or expression (See and expressions), each of whose components is a constant expression,
an array creation expression (See Array creation expressions), each of whose components is a constant expression,
a routine call applied to a constant expression, each of whose arguments is a constant expression other than void, or
a reference to another constant in the same class or in another class using the '::' notation.
There must not be cyclic dependencies among constant initializers. The libraries are designed so that no observable side-effects can occur during constant initialization.
If a type specifier is not provided, then the construct defines one or more successive integer constants. The first identifier is assigned the value zero by default; its value may also be specified by a constant expression of type 'INT'. The remaining identifiers are assigned successive integer values. This is the way to do enumeration types in Sather. It is an error if no type specifier is provided and there is an assignment that is not of type 'INT'.
Each constant definition causes the implicit definition of a reader routine with the same name. It takes no arguments and returns the value of the constant. Its return type is the constant's type. The routine is private if and only if the constant is declared 'private'.
NOTE: The restrictions on constant initialization ensure that the initialization of constants is independant of the order in which classes are initialized, thus promoting compositionality.