Expand/Shrink

class

Definition: [global] [abstract] class identifier [nullable] [dynamic] [extends base]
    { [(public|private)[:]] ( field | method ) [ ',' ... ] }
end class
-- or --
class|identifier variable ( ';' | '=' ( new() | expr ) ) [ ',' ... ]
-- or --
bool res = class|identifier(object o)
Description: As above class can be used in three very distinct ways, almost identically to struct.

Classes are superficially similar to structs, however in structs all fields are implicitly public whereas they are private by default in classes, structs cannot be fully dynamic, and typically classes have methods, while structs normally do not. (In general, Phix allows some reasonable overlap, rather than always strictly saying "NON" (in a cheesy French accent) even when there is no reasonable let alone outright compelling reason to do so. Which reasonably stands to reason, he reasoned reasonably.)

An abstract class (or struct) cannot be instantiated, ie attempts to invoke new() trigger compile-time and/or run-time errors.
By default struct and class variables cannot be set to null, unless the definition contains an explicit nullable clause.
The dynamic and extends clauses are explained separately.

Note that you should never pass a class reference to deep_copy(): doing so would almost guarantee being left with a reference to reclaimed memory or a reclaimed slot in a class instances table, hence the latter now [1.0.5+] has a guard in place to prevent such attempts. There are also some safety checks in builtins/structs.e that prohibit access to a shared reference to a class instance that has (somehow) already been through the delete() process, which would normally only occur when the reference count drops to zero, unless some other bit of code is trying to force the issue, such as by trying to manually destroy an instance-specific delegate, perhaps because setting it to null wasn’t doing it immediately, presumably because there was still some other reference to it when logically there should never be.
pwa/p2js: Not supported.
Example:
class person
--  private: -- (see note)
    string name = "average joe"
    public atom age = 35
    procedure show()
      printf(1,"%s, aged %g\n",{this.name,this.age})
    end procedure
end class
person p = new()
--?p.name  -- error
?p.age    -- 35
p.show() -- average joe, aged 35

If no default value is specified for a field, one will be provided automatically (0/false/""/{}/NULL).

All fields in classes are private by default, whereas in structs they are implicitly public. All methods are public by default.
Explicitly using private on a class field, or public on a method or in a struct, is exactly the same as omitting it/both.
If public or private is followed by ':' it toggles/trashes that default behaviour (as well as applying to the next field/method).
In the above, name is private by default, age is explicitly made public, whereas show is public by default: uncommenting that "private:" would not change name or age, but would make show() private. While initially fields and methods get different privacy defaults, both "private:" and "public:" affect them both, and there is no way to later revert to that initial difference. (You are of course encouraged to group fields and methods appropriately, to minimise the number of times public/private need to be typed in.)

Class methods can use "this." to explicitly refer to class instance fields and methods. It can be omitted provided that doing so remains totally unambiguous, see technicalia.
Implementation: As per struct
See Also: extended, dynamic, javascript.this
Expand/Shrink