Every object inherits some other object called ancestor. This means an inherited object has the same fields as ancestor, and the same value type, unless overridden.
Ancestor Object Evaluation
An object inherits not just an ancestor object. In fact, it inherits an ancestor expression. An ancestor expression is evaluated once per object, in the scope of the enclosing object. When executed in different scopes, an ancestor expression can resolve to different objects.
A := void ( Foo := void ( F := 1 ) Bar := foo ) B := a ( Foo = * ( G := 2 ) )
An ancestor of
b: bar, executed in the scope of enclosing object
b: foo object, which contains a new field
g. So an expression
b: bar: g is valid and returns
Note that when an object inherits an object from another module or inherits a static field, the ancestor expression is static and always resolves to the same ancestor object.
There are limitations of what could be inherited.
A := `1 ~~ A link. B := a->(= 2) ~~ Link target can not be inherited.
An object can not inherit enclosing objects:
A ::= void ( B := void ( B () ~~ This is not possible, as `b` is enclosing object. A () ~~ This is also not possible. /A () ~~ This is possible, because it is an inheritance of ~~ static object `a`, not an enclosing object `a`. A: b () ~~ This is also possible, as this is an inheritance of ~~ field `b` of enclosing object `a`, not an enclosing object `b`. ) )
By default, the inherited object has the same definition as ancestor.
Ancestor := Integer (= 2) Object := Ancestor
In this case
object has the same definition as
ancestor, i.e. its value is
Note that definition depends on the execution scope. So, when inherited, it may result to a different value.
Ancestor := Integer ( Arg 1 := 1 Arg 2 := 2 = Arg 1 * arg 2 ) Object := Ancestor ( Arg 1 = * (= 2) Arg 2 = * (= 4) )
object has value
8, despite it has the same definition as
which value is
The definition can be overridden in inherited object.
Ancestor := Integer (= 2) Object := Ancestor (= 3)
In this case the
object definition is overridden, and its value is
The value type of inherited object should remain the same. That is, if ancestor
has an integer value, an inherited object can’t be updated to have a float
one. The only exception is a void: it can be overridden with definition of any
type. That’s how
Integer object inherits
Void despite it has a different
Every field present in ancestor is propagated to inherited object and can be overridden.
Note that despite private fields are propagated to inherited object, they are not accessible and thus can not be overridden.
Also, an inherited object may declare new fields.
Ancestor := void ( Foo := 2 ) Object := ancestor ( Foo = * (= 3) ~~ Override field "foo" declared in "ancestor". Bar := "new field" ~~ Declare new field "bar". )