8 Language specification 8.1 General organization
8.16 Repeated inheritance
Informative text
Inheritance may be multiple: a class may have any number of parents. A more restrictive solution would limit the benefits of inheritance, so central to object-oriented software engineering.
Because of multiple inheritance, it is possible for a class to be a descendant of another in more than one way. This case is known as repeated inheritance; it raises interesting issues and yields useful techniques, which the following discussion reviews in detail.
End 8.16.1 Definition: Repeated inheritance, ancestor, descendant
Repeated inheritance occurs whenever (as a result of multiple inheritance) two or more of the ancestors of a class D have a common parent A.
D is then called a repeated descendant of A, and A a repeated ancestor of D.
8.16.2 Semantics: Repeated Inheritance rule
Let D be a class and B1, … Bn (n ≥ 2) be parents of D based on classes having a common ancestor A. Let f1, … fn be features of these respective parents, all having as one of their seeds the same feature f of A. Then:
1 Any subset of these features inherited by D under the same final name in D yields a single feature of D.
2 Any two of these features inherited under a different name yield two features of D.
Informative text
This is the basic rule allowing us to make sense and take advantage of inheritance, based on the programmer-controlled naming policy: inheriting two features under the same name yields a single feature, inheriting them under two different names yield two features.
End 8.16.3 Definition: Sharing, replication
A repeatedly inherited feature is shared if case 1 of the Repeated Inheritance rule applies, and replicated if case 2 applies.
8.16.4 Validity: Call Sharing rule Validity code: VMCS
It is valid for a feature f repeatedly inherited by a class D from an ancestor A, such that f is shared under repeated inheritance and not redeclared, to involve a feature g of A other than as the feature of a qualified call if and only if g is, along the corresponding inheritance paths, also shared.
Informative text
If g were duplicated, there would be no way to know which version f should call, or evaluate for the assignment. The “selected” version, discussed below, is not necessarily the appropriate one.
End 8.16.5 Semantics: Replication Semantics rule
Let f and g be two features both repeatedly inherited by a class A and both replicated under the Repeated Inheritance rule, with two respective sets of different names: f1 and f2, g1 and g2.
If the version of f in D is the original version from A and either contains an unqualified call to g or (if f is an attribute) is the target of an assignment whose source involves g, the f1 version will use g1 for that call or assignment, and the f2 version will use g2.
Informative text
This rule (which, unlike other semantic rules, clarifies a special case rather than giving the general semantics of a construct) tells us how to interpret calls and assignments if two separate replications have proceeded along distinct inheritance paths.
End 8.16.6 Syntax: Select clauses
Select
=
Δ select Feature_listInformative text
The Select subclause serves to resolve any ambiguities that could arise, in dynamic binding on polymorphic targets declared statically of a repeated ancestor’s type, when a feature from that type has two different versions in the repeated descendant.
End
8.16.7 Validity: Select Subclause rule Validity code: VMSS A Select subclause appearing in the parent part for a class B in a class D is valid if and only if, for every Feature_name fname in its Feature_list, fname is the final name in D of a feature that has two or more potential versions in D, and fname appears only once in the Feature_list.
Informative text
This rule restricts the use of Select to cases in which it is meaningful: two or more “potential versions”, a term which also has its own precise definition. We will encounter next, in the Repeated Inheritance Consistency constraint, the converse requirement that if there is such a conflict a Select must be provided.
End 8.16.8 Definition: Version
A feature g from a class D is a version of a feature f from an ancestor of D if f and g have a seed in common.
8.16.9 Definition: Multiple versions
A class D has n versions (n ≥ 2) of a feature f of an ancestor A if and only if n of its features, all with different final names in D, are all versions of f.
8.16.10 Validity: Repeated Inheritance Consistency constraint Validity code: VMRC It is valid for a class D to have two or more versions of a feature f of a proper ancestor A if and only if it satisfies one of the following conditions:
1 There is at most one conformance path from D to A.
2 There are two or more conformance paths, and the Parent clause for exactly one of them in D has a Select clause listing the name of the version of f from the corresponding parent.
8.16.11 Definition: Dynamic binding version
For any feature f of a type T and any type U conforming to T, the dynamic binding version of f in U is the feature g of U defined as follows:
1 If f has only one version in U, then g is that feature.
2 If f has two or more versions in U, then the Repeated Inheritance Consistency constraint ensures that either exactly one conformance path exists from U to T, in which case g is the version of f in U obtained along that path, or that a Select subclause name a version of f, in which case g is that version.
8.16.12 Definition: Inherited features
Let D be a class. Let precursors be the list obtained by concatenating the lists of features of every parent of D; this list may contain duplicates in the case of repeated inheritance. The list inherited of inherited features of D is obtained from precursors as follows:
1 In the list precursors, for any set of two or more elements representing features that are repeatedly inherited in D under the same name, so that the Repeated Inheritance rule yields sharing, keep only one of these elements. The Repeated Inheritance Consistency constraint (sharing case) indicates that these elements must all represent the same feature, so that it does not matter which one is kept.
2 For every feature f in the resulting list, if D undefines f, replace f by a deferred feature with the same signature, specification and header comment.
3 In the resulting list, for any set of deferred features with the same final name in D, keep only one of these features, with assertions and header comment joined as per the Join Semantics rule. (Keep the signature, which the Join rule requires to be the same for all the features involved after possible redeclaration.)
4 In the resulting list, remove any deferred feature such that the list contains an effective feature with the same final name. (This is the case in which a feature f, inherited as effective, effects one or more deferred features: of the whole group, only f remains.) 5 All the features of the resulting list have different names; they are the inherited features
of D in their parent forms. From this list, produce a new one by replacing any feature that D redeclares (through redefinition or effecting) with the result of the redeclaration, and retaining any other feature as it is.
6 The result is the list inherited of inherited features of D.
8.16.13 Semantics: Join-Sharing Reconciliation rule
If a class inherits two or more features satisfying both the conditions of sharing under the Repeated Inheritance rule and those of the Join rule, the applicable semantics is the Repeated Inheritance rule.
8.16.14 Definition: Precursor
A precursor of an inherited feature of final name fname is any parent feature — appearing in the list precursors obtained through case 1 of the definition of “Inherited features” — that the feature mergings resulting from the subsequent cases reduce into a feature of name fname.
8.16.15 Validity: Feature Name rule Validity code: VMFN
It is valid for a feature f of a class C to have a certain final name if and only if it satisfies the following conditions:
1 No other feature of C has that same feature name.
2 If f is shared under repeated inheritance, its precursors all have either no Alias or the same alias.
Informative text
Condition 1 follows from other rules: the Feature Declaration rule, the Redeclaration rule and the rules on repeated inheritance. It is convenient to state it as a separate condition, as it can help produce clear error messages in some cases of violation.
Two feature names are “the same” if the lower-case version of their identifiers is the same.
The important notion in this condition is “other feature”, resulting from the above definition of
“inherited features”. When do we consider g to be a feature “other” than f? This is the case whenever g has been declared or redeclared distinctly from f, unless the definition of inherited features causes the features to be merged into just one feature of C. Such merging may only happen as a result of sharing features under repeated inheritance, or of joining deferred features.
Also, remember that if C redeclares an inherited feature (possibly resulting from the joining of two or more), this does not introduce any new (“other”) feature. This was explicitly stated by the definition of “introducing” a feature.
Condition 2 complements these requirements by ensuring that sharing doesn’t inadvertently give a feature more than one alias.
The Feature Name rule crowns the discussion of inheritance and feature adaptation by unequivocally implementing the No Overloading Principle: no two features of a class may have the same name. The only permissible case is when the name clash is apparent only, but in reality the features involved are all the same feature under different guises, resulting from a join or from sharing under repeated inheritance.
End
8.16.16 Validity: Name Clash rule Validity code: VMNC
The following properties govern the names of the features of a class C:
1 It is invalid for C to introduce two different features with the same name.
2 If C introduces a feature with the same name as a feature it inherits as effective, it must rename the inherited feature.
3 If C inherits two features as effective from different parents and they have the same name, the class must also (except under sharing for repeated inheritance) remove the name clash through renaming.
Informative text
This is not a new constraint but a set of properties that follow from the Feature Name rule and other rules. Instead of Eiffel’s customary “This is valid if and only if …” style, more directly useful to the programmer since it doesn’t just tell us how to mess things up but also how to produce guaranteeably valid software, the Name Clash rule is of the more discouraging form “You may not validly write …”. It does, however, highlight frequently applicable consequences of the naming policy, and compilers may take advantage of it to report naming errors.
End