Example 4-8. Examples:
include A a->b, c->, d->private d; private include D e->readonly f; |
include_clause ==> [ private ] include type_specifier [ feature_modifier { , feature_modifier } ] |
feature_modifier ==> ( identifier | iter_name ) -> [ [ private | readonly ] ( identifier | iter_name ) ] |
Implementation inheritance is defined by include clauses. These cause the incorporation of the implementation of the specified type, possibly undefining or renaming features with feature_modifier clauses. The include clause may begin with the keyword 'private', in which case any unmodified included feature is made private. We say that there is an include path from one type to another if there is a sequence of types between them such that each includes the next in the sequence.
The included type specified by the type_specifier may not be a closure type or a type parameter (though type parameters may appear as components of the type specifier). Partial classes may be included. External classes may be included if the interface to the language permits this; external Fortran (See Interfacing with Fortran) and C (See Interfacing with ANSI C) classes may not be included. There mustn't be include paths from reference types to AVAL or from immutable types to AREF (See Built-in classes). There must be no cycle of classes such that each class includes the next, ignoring the values of any type parameters but not their number. If SAME occurs in an include clause, it is interpreted as the eventual type of the class (as late as possible).
Each feature_modifier clause specifies an identifier which must be the name of at least one feature in the included class. If no clause follows the '->' symbol, then the named features are not included in the class. If an identifier follows the '->' symbol, then it becomes the new name for the features. In this case, the listed features are included as part of the public interface unless they are specified as 'private' or 'readonly'. Identifiers may only be renamed as identifiers and iterator names may only be renamed by iterator names. It is an error if there are no appropriate methods to rename in the included class, and both a reader and a writer method (See Each attribute definition causes the definition of a reader and a writer routine with the same name. The reader routine takes no arguments and returns the value of the attribute. Its declared return type is the attribute's type. It is private if the attribute is declared 'private'.) must exist if 'readonly' is used.
A class may not explicitly define two methods whose signatures conflict (See We say that the method signature f conflicts with g when). A class may not define a routine whose signature conflicts with either the reader or the writer routine of any of its attributes (whether explicitly defined or included from other classes). If a method is explicitly defined in a class, it overrides all conflicting methods from included classes. The implicit reader and writer routines of a class's attributes, shareds, and constants also override any included routines and must not conflict with each other. If an included method is not overridden, then it must not conflict with another included method; feature modification clauses can be used to resolve any conflicts.