Expand/Shrink

extended

Definition: class identifier extends base
    { [(public|private)[:]] ( field | method ) [ ',' ... ] }
end class
-- or --
class|identifier variable ( ';' | '=' ( new() | expr ) ) [ ',' ... ]
-- or --
bool res = class|identifier(object o)
Description: Classes can also be extended, to create an inheritance hierarchy, or just simply embedded.
pwa/p2js: Not supported.
Extending:
class politician extends person
    string job = "habitual liar"
    procedure show()
      printf(1,"%s aged %g, %s\n",{this.name,this.age,this.job})
    end procedure
end class
politician aj = new(),
           mp = new({"boris",3.75})
aj.show() -- average joe aged 35, habitual liar
mp.show() -- boris aged 3.75, habitual liar

When a class(/struct) is extended, all fields are copied along with any defaults and privacy settings.
You can store every politician in a person variable, but not the other way round.
You can store every politician and every person in a class variable, ie the lowest level builtin type.
If you also had class honest_man extends person, a person can hold an honest_man or a politician, but an honest_man variable cannot hold a politician, and a politician variable cannot hold a honest_man! In other words variables of the base class (as in "extends base") can hold the extended class[es], but not vice-versa.
Embedding:
person jrm = new({"jacob",50})

class mogg
    person p = jrm
    string job = "minister for the early 1800s"
    procedure show()
      printf(1,"%s aged %g, %s\n",{this.p.name,this.p.age,this.job})
    end procedure
end class
mogg m = new() -- or new({jrm,"oaf"}) or new({new("person",{"jacob",50}),"oaf"})
jrm.show() -- jacob, aged 50
m.p.show() -- jacob, aged 50
m.show() -- jacob aged 50, minister for the early 1800s

When a class(/struct) is embedded, unless otherwise specified the default is null and fields require extra subscripting, ie/eg this.p.name vs. this.name. Note that embedding naturally (/usually) leads to shared references to a single instance; if the above inlined person p = new() it would behave the same, as opposed to an explicit new() in a constructor routine.
Private fields of embedded classes can only be accessed via explicit getters and setters, rather than anything resembling "friends".
As shown, you cannot override methods in embedded fields, and nothing stops you having a same-named-method at a different level.
(Obviously you could easily declare "class person_with_overidden_show extends person" and extend/embed an instance of that instead.)
Inlining the new() of jrm on the "mogg m =" line would as shown require an explicit "person" (if that’s not an insult).
When a class is extended, all fields are given the inherited defaults, whereas an embedded class gets a null default (assuming nowt like jrm above).
Conversely, extending a person might need the same information updating in more than one place, unlike a single/shared new() being embedded.
You cannot store a mogg in a person variable or vice versa(!), but can store both in their common ancestor, which in this case is the root builtin class.
Implementation: As per struct
See Also: class
Expand/Shrink