## §4.9 Callin inheritance

This section defines how callin bindings and callin methods relate to inheritance.

### §4.9.1 Base side inheritance↑ §4.9

Generally, a callin binding affects all sub-types of its bound base. Specifically, if a role type `R` bound to a base type `B` defines a callin binding `rm <- callin_modifier bm`, the following rules apply:

#### (a) Effect on sub-classes

The callin binding also effects instances of any type `BSub` that is a sub-type of `B`. If `BSub` overrides the bound base method `bm`, the overridden version is generally affected, too. However, if `bm` covariantly redefines the return type from its super version, the callin binding has to explicitly specify if the covariant sub-class version should be affected, too (see §4.9.3.(b)).

#### (b) No effect on super-classes

The binding never affects an instance of any super-type of `B` even if the method `bm` is inherited from a super-class or overrides an inherited method. This ensures that dispatching to a role method due to a callin binding always provides a base instance that has at least the type declared in the role's `playedBy` clause.

For corresponding definitions regarding static methods see §4.7.(e).

### §4.9.2 Role side inheritance↑ §4.9

Any sub-type of `R` inherits the given callin binding (for overriding of bindings see §4.8.(e)). If the sub-role overrides the role method `rm` this will be considered for dynamic dispatch when the callin binding is triggered.

### §4.9.3 Covariant return types↑ §4.9

Since version 5, Java supports the covariant redefinition of a method's return type (see JLS 8.4.5). This is not supported for `callin` methods (§4.9.3.(a)). If base methods with covariant redefinition of the return type are to be bound by a callin binding the subsequent rules ensure that type safety is preserved. Two constraints have to be considered:

1. When a callin method issues a base-call or calls its tsuper version, this call must produce a value whose type is compatible to the enclosing method's declared return type.
2. If a replace-bound role method returns a value that is not the result of a base-call, it must be ensured that the return value actually satisfies the declared signature of the bound base method.

#### (a) No covariant callin methods

A method declared with the `callin` modifier that overrides an inherited method must not redefine the return type with respect to the inherited method. This reflects that fact that an inherited callin binding should remain type-safe while binding to the new, overriding role method. Binding a covariant role method to the original base method would break constraint (1) above.

#### (b) Capturing covariant base methods

If a callin binding should indeed affect not only the specified base method but also overriding versions which covariantly redefine the return type, the binding must specify the base method's return type with a "+" appended to the type name as in

    void rm() <- before RT+ bm();

Without the "+" sign the binding would only capture base methods whose return type is exactly `RT`; by appending "+" also sub-types of `RT` are accepted as the declared return type.

#### (c) Covariant replace binding

When using the syntax of §4.9.3.(b) to capture base methods with covariant return types in a callin binding with the `replace` modifier, the role method must be specified using a free type parameter as follows:

    <E extends RT> E rm() <- replace RT+ bm();

The role method `rm` referenced by this callin binding must use the same style of return type using a type parameter. The only possible non-null value of type `E` to be returned from such method is the value provided by a base-call or a tsuper-call.
This rule enforces the constraint (2) above.
Note that this rule is further generalized in §4.10.

##### Binding a parametric role method

1

    public class SuperBase {

2

        SuperBase foo() { return this; }

3

        void check() { System.out.print("OK"); }

4

    }

5

    public class SubBase extends SuperBase {

6

        @Override

7

        SubBase foo() { return this; }

8

        void print() { System.out.print("SubBase"); }

9

        String test() {

10

            this.foo().print(); // print() requires a SubBase

11

        }

12

    }

13

14

    public team class MyTeam {

15

        protected class R playedBy SuperBase {

16

            callin <E extends SuperBase> E ci() {

17

    			E result= base.ci();

18

    			result.check(); // check() is available on E via type bound SuperBase

19

    			return result;

20

            }

21

            <E extends SuperBase> E  ci() <- replace SuperBase+ foo();

22

        }

23

    }

##### Explanation:

- Method `SubBase.foo` in line 7 redefines the return type from `SuperBase` (inherited version) to `SubBase`, thus clients like the method call in line 10 must be safe to assume that the return value will always conform to `SubBase`.
- The callin binding in line 21 explicitly captures both versions of `foo` by specifying `SuperBase+` as the expected return type. Thus, if an instance of `MyTeam` is active at the method call in line 10, this call to `foo` will indeed be intercepted even though this call is statically known to return a value of type `SubBase`.
- The callin method in lines 16-20 has a return type which is not known statically, but the return type is represented by the type variable `E`. Since the base call is known to have the exact same signature as its enclosing method, the value provided by the base call is of the same type `E` and thus can be safely returned from `ci`. Note, that no other non-null value is known to have the type `E`.
- By specifying `SuperBase` as an upper bound for the type `E` the callin method `ci` may invoke any method declared in type `SuperBase` on any value of type `E`. For an example see the call to `check` in line 18.

As an aside note that the above example uses type `SuperBase` in an undisciplined way: within role `R` this type is bound using `playedBy` and the same type is also used directly (as the upper bound for `E`). This is considered bad style and it is prohibited if `SuperBase` is imported using an base import (§2.1.2.(d)). Here this rule is neglegted just for the purpose of keeping the example small.