Types
Types are the fundamental building blocks of the Oxygene language.
There are three broad categories of types:
-
Predefined Simple Types are small and atomic types that are built into the language to represent the simplest of data: numbers, booleans, strings, and the like.
-
Custom Types are types not defined by the language, but by yourself or provided by base libraries or frameworks. Where standard types are universal in application, custom types usually serve a specific purpose.
- Classes
- Records
- Interfaces
- Enums
- Blocks (a.k.a. Delegates)
-
Modified Types are defined by the language itself, and extend or modify the behavior of a regular type, or form complex combinations, such as arrays, sequences, tuples or pointers of a given other type.
-
Anonymous Types are custom types (Classes or Records) that are instantiated on the fly without being explicitly declared or given a name.
Oxygene also has support for declaring types in special ways:
-
Generic Types are classes (or records and interfaces) where one or more of the other types that the class interacts with (for example to receive or return as a parameter from methods) is not well-defined, but kept generic. This allows for the class to be implemented in a fashion that it can work with or contain different type parameters. Only when a generic type is used, a concrete type is specified.
-
Partial Types are regular types that are declared and implemented across multiple source files – commonly to keep a large class easier to maintain, or because one part of the class is generated by a tool.
-
Mapped Types allow you to provide the definition of a type that will not exist at runtime, but merely map to a different, already existing type.
-
Type Extensions can expand an existing type with new methods or properties (but not new data), even if that type was originally declared in an external library.
-
Type Aliases can give a new name to an existing type.
Type Declarations
Custom Types and Aliases to existing types can be declared in the interface
or implementation
section of any source file, after a type
keyword.
Each type declaration starts with the type's name, followed by an equal sign (=
) and followed by optional Type Modifiers, which can also include a Visibility Lebel, followed by the details of the type declaration as specified in the individual custom type topics referenced above.
type
MyClass = sealed class
end;
MyInteger = public type Integer;
In the above example, MyClass
ands MyInteger
are the type names. They are followed by the equal sign, and the sealed
and public type
modifiers, respectively. Finally class ... end
and Integer
are the type declaration itself (a Class declaration and an Alias, in this case).
Type References
While Type Declarations, covered above, introduce a new type name, the most common interaction with types is to reference existing ones.
Most types, including Simple Types and Custom Types, are referenced using simply their name – either their short name, or their fully qualified name including the Namespace.
var x: SomeClass; // Variable x is declared referencing the SomeClass type by name.
By contrast, Modified Types are referenced using a particular syntax specific to the type, such as the array of
, sequence of
or nullable
keywords, often combined with a type name.
var x: array of SomeRecord; // Variable x is as an *array* of the type referred to by name.
var y: nullable Integer; // Variable x is as a *nullable* version of the name's simple type.
On the Cocoa platform, type references can be prefixed with Storage Modifiers to determine how they interact with ARC.
On the Island-based platform, type references can be prefixed with a Life-Time Strategy Modifier to determine how their lifetime is managed (although doing so explicitly is rarely needed). Storage Modifiers, as discussed above, are also supported when working with Cocoa or Swift objects Cocoa project.
More on Type Names
Every named type (Simple Types and Custom Types) in Oxygene can be referred to either by its short name (e.g. MyClass
), or what is called a fully qualified name that includes a full namespace (e.g. MyCompany.MyProject.MyClass
).
When declaring types with a simple name, the type will automatically be placed within the namespace that is declared at the top of the file alongside the namespace
keyword. Alternatively, a fully qualified name can be provided in the declaration to override the namespace.
namespace MyCompany.MyProject
interface
type
MyClass = class // full name will be MyCompany.MyProject.MyClass
end;
MyCompany.OtherProject.OtherClass = class // full name will be MyCompany.OtherProject.OtherClass
end;
You can read more about this in the Namespaces topic.