Classes

A class is a data structure that may contain data members (Constants, Fields and Properties, as well as actions that work with that data (Methods).

Classes take part in a hierarchy of types and can descend from each other to form that hierarchy (more on that below). An instance of a class is commonly referred to as an "object".

A class type is declared using the class keyword, followed by zero or more member declarations, and closed off with the end keyword. Optionally, a base class and/or a list of one or more interfaces implemented by the class can be provided in parenthesis behind the class keyword:

type
  MyClass = public class(Object, IMyInterface)
  private
    fName: String;
    fValue: Integer;
  public
    property Name: String read fName;
    property Value: Integer read fValue;
  end;

Like all custom types, classes can be nested in other types with the nested in syntax.

Members

Classes can contain Type Members, including Fields, Properties and even Methods. Also like in classes, the members can be grouped in Visibility Sections.

Invariants

Classes can define Invariants to help ensure a consistent state. Invariants are boolean expressions that will automatically be enforced by the compiler every time a method or property accessor finishes.

Nested Types

Classes can also define Nested Types. Nested types are like regular custom types, except they are considered part of the class and their visibility can be scoped as granular as all class Members.

Nested types are declared using the nested in syntax, and (outside of the containing class) are referred to in the same way as static class members would – prefixed with the name of the class, and dot.

Refer to the Nested Types topic for more details.

Polymorphism

As hinted above, classes are part of a class hierarchy, where each class (except the root) has an ancestor class that it descends from and extends. You can think of this hierarchy as a tree, with a common root (Object).

Classes can be treated polymorphically. That means an object (a concrete instance of a class) can be treated the same as any any of its base classes. This allows code to be written that can work with a base class (or even Object itself), and it can be applied to any descendant of the same class, as well.

Individual members of a class can be virtual, which means that descendant classes can override their implementation to provide more specific behavior. When code working with a common base class accesses virtual members, at runtime execution is automatically passed to the implementation for the concrete instance.

For example, code could be written for a list of Person classes, which, at runtime, includes various concrete subclasses or persons, such as Employee, Manager, FamilyMember or the like. The code has access to all (visible) members declared on Person, but might end up transparently calling more specific implementations of these members provided by Employee, Manager or FamilyMember.

Please refer to the Polymorphism topic in the Concepts section, for details.

Abstract Classes

A class can be marked with the abstract Modifier, to indicate that it is an abstract base class. Abstract classes cannot be instantiated, and they may (but don't have to) contain abstract Members – that is, members that have been defined on the class, but not implemented.

Descendants from an abstract classes class can become non-abstract, if they provide overriden implementations for all abstract members.

Consider a class hierarchy of vehicles, where the base class Vehicle can represent any kind of vehicle, but not a concrete type. It might provide an abstract Drive method, but no implementation (since there is no one way to drive "any vehicle"). It makes no sense to create an instance of a Vehicle. Concrete subclasses such as Car, Train and Bike could provide implementations for the Drive method.

Yet, even though Vehicle is abstract, code can be written that knows how to call Drive on any vehicle.

Again, please refer to the Polymorphism topic in the Concepts section, for details.

Sealed Classes

A class can be marked with the sealed Modifier, to prevent further subclassing.

Extension Classes

Extension Classes can add properties, methods, operators and events to an existing type (but not add anything that requires storage, like fields, events or stored properties). These become available to callers if this type is in scope for the caller. The first type in the ancestor defines which type gets extended; optional interfaces can be used to add/implement as interfaces allowing the type to be compatible with that interface.

Read more about Extension Classes here.

Type Visibility

The visibility of a class type can be controlled by applying a Visibility Modifier on the declaration. The default visibility is assembly.

Other Modifiers

A number of other Type Modifiers can be applied to classes:

  • abstract Forces the class to be abstract; see above.
  • extension Makes this an extension class; see above and Extensions.
  • mapped Makes this a mapped class; see Mapped Types.
  • partial Partial can be used to spread a type over several files in the same project. All parts must have this modifier then.
  • readonly Makes this class readonly. All fields in it will be readonly and can only be set by a constructor and not modified afterwards.
  • static Static classes are classes with only static members. The class modifier is implied on all members.

See Also