# Classes & Objects
DWScript is fully object-oriented, supporting classes, inheritance, polymorphism, and encapsulation.
## Usage Examples
```pascal
type
TAnimal = class
FName : String;
constructor Create(const name : String);
begin
FName := name;
end;
procedure Speak; virtual;
begin
PrintLn(FName + ' makes a sound');
end;
end;
type
TDog = class(TAnimal)
procedure Speak; override;
begin
PrintLn(FName + ' barks');
end;
end;
var myPet := new TDog('Buddy');
myPet.Speak;
// OUTPUT
// Buddy barks
```
## Classes
A class is a blueprint for objects. In DWScript, classes support several modifiers to control inheritance and instantiation.
### Declaration Syntax
While you can use the standard `procedure` and `function` keywords, DWScript also supports the `method` keyword as a unified alternative for declaring any member subroutine within a class. It is fully interchangeable with `procedure` (if no return type) or `function` (if return type is specified).
```pascal
type
TMyClass = class
method DoSomething; begin end;
method Calculate: Integer; begin Result := 0; end;
class method StaticAction; begin end;
end;
// OUTPUT NONE
```
| Modifier | Description |
| :--- | :--- |
| `abstract` | The class cannot be instantiated directly. It must be inherited. |
| `sealed` | The class cannot be inherited from. |
| `static` | A class that only contains static (class) members. It cannot be instantiated. |
| `partial` | Allows splitting a class definition across multiple files or sections. |
### Static Classes
A static class is used to group related global functions and variables. It cannot be instantiated using `new` or `Create`.
```pascal
type
TUtils = static class
class procedure SayHello;
begin
PrintLn('Hello from Static Class');
end;
end;
TUtils.SayHello;
// var u := new TUtils; // Error: Cannot instantiate static class
// OUTPUT
// Hello from Static Class
```
### Partial Classes
The `partial` modifier allows a class to be defined in multiple parts. This is useful for large classes or when combining generated code with manual code.
```pascal
type
TBigClass = partial class
procedure MethodA; begin PrintLn('A'); end;
end;
type
TBigClass = partial class
procedure MethodB; begin PrintLn('B'); end;
end;
var obj := new TBigClass;
obj.MethodA;
obj.MethodB;
// OUTPUT
// A
// B
```
## Inner Classes (Nested Types)
DWScript supports defining classes within other classes. These are known as inner or nested classes. They are useful for grouping helper classes that are only relevant to the outer class.
```pascal
type
TOuter = class
type
TInner = class
function GetMsg: String;
begin
Result := 'Hello from Inner';
end;
end;
procedure Run;
begin
var i := new TInner;
PrintLn(i.GetMsg);
end;
end;
var o := new TOuter;
o.Run;
// OUTPUT
// Hello from Inner
```
## Constructors & Destructors
Constructors initialize new object instances. Unlike many languages that use a fixed name like `constructor` or `__init__`, DWScript supports **named constructors**, following classic Pascal conventions.
### Instantiation Syntax
You can instantiate an object in two ways:
* **Classic Pascal:** `TMyClass.Create(args)`. This is the traditional way to call a specific named constructor.
* **Modern Syntax:** `new TMyClass(args)`. This uses the constructor marked with the `default` keyword.
### The "default" Keyword
A class can designate one constructor as the default. This allows the `new` keyword to be used without specifying the constructor name.
```pascal
type
TUser = class
constructor Create(name: String); default;
begin
inherited Create; // Call parent constructor
// ...
end;
end;
var u := new TUser('Alice'); // Calls TUser.Create
// OUTPUT NONE
```
### Overloaded Constructors
You can have multiple constructors with the same name but different parameters by using the `overload` modifier.
```pascal
type
TPoint = class
constructor Create; overload; begin end;
constructor Create(x, y: Integer); overload; begin end;
end;
// OUTPUT NONE
```
### Virtual Constructors & Metaclasses
Constructors can be `virtual`. When combined with **[Metaclasses](/lang/oop/oop_metaclasses)** (class references), this allows for powerful dynamic instantiation patterns, such as factories, where the specific class to be created is determined at runtime.
```pascal
type
TBase = class(TObject)
constructor Create; virtual; begin end;
end;
type
TDerived = class(TBase)
constructor Create; override; begin end;
end;
type
TBaseClass = class of TBase;
var cls: TBaseClass := TDerived;
var obj := cls.Create;
// OUTPUT NONE
```
This "factory" pattern is a core part of DWScript's metaprogramming capabilities, allowing the system to work with types as first-class values.
### Destructors
Destructors are named `Destroy` and are used to clean up resources.
Because DWScript uses ARC (Automatic Reference Counting), they are called automatically when the reference count reaches zero. For more details, see **[Memory Management](/lang/oop/oop_memory)**.
It is best practice to always mark your destructor with `override` and call `inherited` as the last statement to ensure the base class cleanup also runs.
## Class Operators
Classes can define custom behavior for standard operators using the `class operator` syntax. This allows objects to interact naturally with language operators like `+`, `-`, `in`, and implicit casts.
The syntax maps an operator to a specific method (either a static class method or a standard method).
### Customizing Arithmetic/Assignment
You can define operators like `+=` to handle custom addition logic.
```pascal
type
TLogger = class
Buffer: String;
procedure Append(s: String);
begin
Buffer := Buffer + s + #13#10;
end;
// Map += operator to Append method
class operator += String uses Append;
end;
var log := new TLogger;
log += 'Line 1';
log += 'Line 2';
PrintLn(log.Buffer);
// OUTPUT
// Line 1
// Line 2
```
### Customizing 'in' Operator
The `in` operator is particularly powerful. You can define how your class responds when checking if a value "is in" the object.
```pascal
type
TRange = class
Min, Max: Integer;
constructor Create(aMin, aMax: Integer);
begin
Min := aMin; Max := aMax;
end;
function Contains(i: Integer): Boolean;
begin
Result := (i >= Min) and (i <= Max);
end;
// Map 'in' operator to Contains method
class operator in Integer uses Contains;
end;
var r := new TRange(10, 20);
if 15 in r then
PrintLn('15 is in range');
if 5 not in r then
PrintLn('5 is outside range');
// OUTPUT
// 15 is in range
// 5 is outside range
```
## Advanced Features
Object Pascal in DWScript includes several advanced features for building robust applications:
* **[Properties](/lang/oop/oop_properties)**: Controlled data access.
* **[Metaclasses](/lang/oop/oop_metaclasses)**: Dynamic class references and instantiation.
* **[Memory Management](/lang/oop/oop_memory)**: Understanding ARC and Garbage Collection.
* **[Interfaces](/lang/oop/interfaces)**: Defining contracts for polymorphism.
Classes & Objects
DWScript is fully object-oriented, supporting classes, inheritance, polymorphism, and encapsulation.
Usage Examples
type
TAnimal =class
FName :String;constructor Create(const name :String);begin
FName := name;end;procedure Speak;virtual;begin
PrintLn(FName +' makes a sound');end;end;type
TDog =class(TAnimal)procedure Speak;override;begin
PrintLn(FName +' barks');end;end;var myPet :=new TDog('Buddy');
myPet.Speak;
Result
Buddy barks
Classes
A class is a blueprint for objects. In DWScript, classes support several modifiers to control inheritance and instantiation.
Declaration Syntax
While you can use the standard procedure and function keywords, DWScript also supports the method keyword as a unified alternative for declaring any member subroutine within a class. It is fully interchangeable with procedure (if no return type) or function (if return type is specified).
type
TMyClass =class
method DoSomething;beginend;
method Calculate:Integer;begin Result :=0;end;class method StaticAction;beginend;end;
Modifier
Description
abstract
The class cannot be instantiated directly. It must be inherited.
sealed
The class cannot be inherited from.
static
A class that only contains static (class) members. It cannot be instantiated.
partial
Allows splitting a class definition across multiple files or sections.
Static Classes
A static class is used to group related global functions and variables. It cannot be instantiated using new or Create.
type
TUtils =staticclassclassprocedure SayHello;begin
PrintLn('Hello from Static Class');end;end;
TUtils.SayHello;// var u := new TUtils; // Error: Cannot instantiate static class
Result
Hello from Static Class
Partial Classes
The partial modifier allows a class to be defined in multiple parts. This is useful for large classes or when combining generated code with manual code.
DWScript supports defining classes within other classes. These are known as inner or nested classes. They are useful for grouping helper classes that are only relevant to the outer class.
type
TOuter =classtype
TInner =classfunction GetMsg:String;begin
Result :='Hello from Inner';end;end;procedure Run;beginvar i :=new TInner;
PrintLn(i.GetMsg);end;end;var o :=new TOuter;
o.Run;
Result
Hello from Inner
Constructors & Destructors
Constructors initialize new object instances. Unlike many languages that use a fixed name like constructor or __init__, DWScript supports named constructors, following classic Pascal conventions.
Instantiation Syntax
You can instantiate an object in two ways:
Classic Pascal:TMyClass.Create(args). This is the traditional way to call a specific named constructor.
Modern Syntax:new TMyClass(args). This uses the constructor marked with the default keyword.
The "default" Keyword
A class can designate one constructor as the default. This allows the new keyword to be used without specifying the constructor name.
type
TUser =classconstructor Create(name:String);default;begininherited Create;// Call parent constructor// ...end;end;var u :=new TUser('Alice');// Calls TUser.Create
Overloaded Constructors
You can have multiple constructors with the same name but different parameters by using the overload modifier.
type
TPoint =classconstructor Create;overload;beginend;constructor Create(x, y:Integer);overload;beginend;end;
Virtual Constructors & Metaclasses
Constructors can be virtual. When combined with Metaclasses (class references), this allows for powerful dynamic instantiation patterns, such as factories, where the specific class to be created is determined at runtime.
This "factory" pattern is a core part of DWScript's metaprogramming capabilities, allowing the system to work with types as first-class values.
Destructors
Destructors are named Destroy and are used to clean up resources.
Because DWScript uses ARC (Automatic Reference Counting), they are called automatically when the reference count reaches zero. For more details, see Memory Management.
It is best practice to always mark your destructor with override and call inherited as the last statement to ensure the base class cleanup also runs.
Class Operators
Classes can define custom behavior for standard operators using the class operator syntax. This allows objects to interact naturally with language operators like +, -, in, and implicit casts.
The syntax maps an operator to a specific method (either a static class method or a standard method).
Customizing Arithmetic/Assignment
You can define operators like += to handle custom addition logic.
type
TLogger =class
Buffer:String;procedure Append(s:String);begin
Buffer := Buffer + s +#13#10;end;// Map += operator to Append methodclassoperator+=Stringuses Append;end;var log :=new TLogger;
log +='Line 1';
log +='Line 2';
PrintLn(log.Buffer);
Result
Line 1
Line 2
Customizing 'in' Operator
The in operator is particularly powerful. You can define how your class responds when checking if a value "is in" the object.
type
TRange =class
Min, Max:Integer;constructor Create(aMin, aMax:Integer);begin
Min := aMin; Max := aMax;end;function Contains(i:Integer):Boolean;begin
Result :=(i >= Min)and(i <= Max);end;// Map 'in' operator to Contains methodclassoperatorinIntegeruses Contains;end;var r :=new TRange(10,20);if15in r then
PrintLn('15 is in range');if5notin r then
PrintLn('5 is outside range');
Result
15 is in range
5 is outside range
Advanced Features
Object Pascal in DWScript includes several advanced features for building robust applications: