The Freya Programming Language

Classes

See also

Classes are reference types that encapsulate both data and code.

Class declaration

This is the syntax of a class declaration:

classname = class genericsopt inheritanceopt
    class-section...
end;

A class section is defined like this:

access-modifier
    class-member...

where an access-modifier is any of these:

Access level Meaning
public Public features can be accessed from any location.
protected Protected features can only be accessed by classes descending from the declaring class.
private Private features can only be accessed by the declaring class.
internal Internal features can only be accessed by classes located in the same assembly as the declaring class.
protected or internal Protected internal features can only be accessed by derived classes and by any other class in the same assembly.
protected and internal These features can only be accessed by derived class located in the same assembly.

Some members may be optionally preceded by the static modifier. Members that support the static modifier are:

Though a class or record may have a static constructor, static constructors are not declared with the class, and they are always directly included in the implementation section for the class or record.

Complex = class(IEquatable[Complex])
private
    RealPart, ImagPart: Double;
public
    constructor(RealPart, ImagPart: Double);

    property Radius: Double; readonly;
    method Equals(Other: Complex): Boolean;
end;

Class implementation

The implementation of this class takes place in a separated section inside the same file:

implementation for Complex is

    constructor(RealPart, ImagPart: Double);
    begin
        Self.RealPart := RealPart;
        Self.ImagPart := ImagPart;
    end;

    property Radius: Double;
    begin
        Result := System.Math.Sqrt(RealPart * RealPart + ImagPart * ImagPart);
    end;

    method Equals(Other: Complex): Boolean;
    begin
        Result := RealPart = Other.RealPart and ImagPart = Other.ImagPart;
    end;

An implementation section may contain:

There cannot be more than one implementation section for a given class, except when dealing with partial classes.

Inline implementation

When a class has few members that need an implementation, it is better to bring the class implementation as nearer to the declaration as posible:

<DefaultMember('Items')>
Ray = sealed class
public
    Origin, Direction: Vector;
    property Items[Time: Double]: Vector; readonly;
implementation

    property Items(Time: Double): Vector;
    begin
        Result.X := Origin.X + Time * Direction.X;
        Result.Y := Origin.Y + Time * Direction.Y;
        Result.Z := Origin.Z + Time * Direction.Z;
    end;

end;

This time, the implementation section has been included inside the class, as its final section. Still, we have a declaration for the Items indexer and a separate implementation. We can move further and implement the Items property in the public section:

<DefaultMember('Items')>
Ray = sealed class
public
    Origin, Direction: Vector;

    property Items[Time: Double]: Vector;
    begin
        Result.X := Origin.X + Time * Direction.X;
        Result.Y := Origin.Y + Time * Direction.Y;
        Result.Z := Origin.Z + Time * Direction.Z;
    end;
end;

Inline implementation is only recommended for small classes, with a handful of members. Note the differences in this case:

Some members must be always declared in an implementation section. They include interface delegations, static constructors and explicit interface implementations.

See also

The Freya Programming Language
Static classes
Constant types
Type declarations
Nested types
Record declarations
Interface declarations
Type members