Classes

XXML supports object-oriented programming with classes, constructors, methods, and inheritance.

Class Declaration

Classes are declared using square brackets with visibility sections:

xxml
[ Class <ClassName> Final Extends BaseClass
    [ Public <>
        // Public members
    ]
    [ Private <>
        // Private members
    ]
    [ Protected <>
        // Protected members
    ]
]

Note

The Final keyword indicates the class cannot be extended. Use Extends None for classes with no base class.

Properties

Properties are declared with their type and ownership modifier inside visibility sections:

person.xxml
[ Class <Person> Final Extends None
    [ Private <>
        Property <name> Types String^;
        Property <age> Types Integer^;
    ]

    [ Public <>
        Property <isActive> Types Bool^;
    ]
]

Constructors

Default Constructor

Use = default for a simple default constructor:

xxml
[ Class <Widget> Final Extends None
    [ Public <>
        Constructor = default;
    ]
]

Custom Constructor

Custom constructors take parameters and initialize properties using the arrow syntax:

xxml
[ Class <Person> Final Extends None
    [ Private <>
        Property <name> Types String^;
        Property <age> Types Integer^;
    ]

    [ Public <>
        Constructor Parameters (
            Parameter <n> Types String^,
            Parameter <a> Types Integer^
        ) ->
        {
            Set name = n;
            Set age = a;
        }
    ]
]

// Creating an instance
Instantiate Person^ As <person> = Person::Constructor(
    String::Constructor("Alice"),
    Integer::Constructor(30)
);

Methods

Instance Methods

Methods are declared with Method, return type, parameters, and Do:

xxml
[ Class <Calculator> Final Extends None
    [ Public <>
        Constructor = default;

        Method <add> Returns Integer^ Parameters (
            Parameter <a> Types Integer%,
            Parameter <b> Types Integer%
        ) Do
        {
            Return a.add(b);
        }

        Method <greet> Returns None Parameters () Do
        {
            Run Console::printLine(String::Constructor("Hello from Calculator!"));
        }
    ]
]

// Calling methods
Instantiate Calculator^ As <calc> = Calculator::Constructor();
Instantiate Integer^ As <sum> = calc.add(Integer::Constructor(5), Integer::Constructor(3));
Run calc.greet();

Method Return Types

Return TypeUse CaseExample
Type^Returns new owned valueFactory methods, creating new data
Type&Returns reference to internal dataGetters, accessing properties
NoneNo return valueSide-effect methods (print, modify)
xxml
// Returns owned value (creates new data)
Method <createMessage> Returns String^ Parameters () Do
{
    Return String::Constructor("New message");
}

// Returns reference (borrows internal data)
Method <getName> Returns String& Parameters () Do
{
    Return &name;
}

// Returns nothing (performs action)
Method <printInfo> Returns None Parameters () Do
{
    Run Console::printLine(name);
}

Access Modifiers

Public

Accessible from anywhere

Protected

Accessible by class and subclasses

Private

Only accessible within the class

xxml
[ Class <Account> Final Extends None
    [ Private <>
        // Only accessible within this class
        Property <balance> Types Integer^;
    ]

    [ Protected <>
        // Accessible by this class and subclasses
        Property <accountId> Types String^;
    ]

    [ Public <>
        // Accessible from anywhere
        Method <getBalance> Returns Integer& Parameters () Do
        {
            Return &balance;
        }
    ]
]

Inheritance

Classes can extend other classes using Extends:

xxml
[ Class <Animal> Final Extends None
    [ Protected <>
        Property <name> Types String^;
    ]

    [ Public <>
        Constructor Parameters (Parameter <n> Types String^) ->
        {
            Set name = n;
        }

        Method <speak> Returns None Parameters () Do
        {
            Run Console::printLine(String::Constructor("..."));
        }
    ]
]

[ Class <Dog> Final Extends Animal
    [ Public <>
        Constructor Parameters (Parameter <n> Types String^) ->
        {
            Set name = n;
        }

        Method <speak> Returns None Parameters () Do
        {
            Run Console::printLine(String::Constructor("Woof!"));
        }
    ]
]

Tip

Subclasses can override methods from the parent class. Protected members are accessible in subclasses.

Enumerations

Define a set of named constants:

xxml
[ Enumeration <Status>
    Value <PENDING> = 0;
    Value <ACTIVE> = 1;
    Value <COMPLETED> = 2;
    Value <CANCELLED> = 3;
]

// Usage
Instantiate Status^ As <currentStatus> = Status::ACTIVE;

If (currentStatus.equals(Status::COMPLETED)) -> {
    Run Console::printLine(String::Constructor("Task is done"));
}

Complete Example

bank_account.xxml
1#import Language::Core;
2
3[ Class <BankAccount> Final Extends None
4 [ Private <>
5 Property <owner> Types String^;
6 Property <balance> Types Integer^;
7 ]
8
9 [ Public <>
10 Constructor Parameters (
11 Parameter <ownerName> Types String^,
12 Parameter <initialBalance> Types Integer^
13 ) ->
14 {
15 Set owner = ownerName;
16 Set balance = initialBalance;
17 }
18
19 Method <deposit> Returns None Parameters (Parameter <amount> Types Integer%) Do
20 {
21 Set balance = balance.add(amount);
22 }
23
24 Method <withdraw> Returns Bool^ Parameters (Parameter <amount> Types Integer%) Do
25 {
26 If (balance.greaterThanOrEqual(amount)) -> {
27 Set balance = balance.subtract(amount);
28 Return Bool::Constructor(true);
29 } Else -> {
30 Return Bool::Constructor(false);
31 }
32 }
33
34 Method <getBalance> Returns Integer& Parameters () Do
35 {
36 Return &balance;
37 }
38
39 Method <printStatement> Returns None Parameters () Do
40 {
41 Run Console::printLine(String::Constructor("Account: ").concat(owner));
42 Run Console::printLine(String::Constructor("Balance: ").concat(balance.toString()));
43 }
44 ]
45]
46
47[ Entrypoint
48 {
49 Instantiate BankAccount^ As <account> = BankAccount::Constructor(
50 String::Constructor("Alice"),
51 Integer::Constructor(1000)
52 );
53
54 Run account.deposit(Integer::Constructor(500));
55 Run account.withdraw(Integer::Constructor(200));
56 Run account.printStatement();
57
58 Exit(0);
59 }
60]

Best Practices

  • Keep properties private and expose them through methods
  • Use ^ owned returns for factory methods creating new data
  • Use & reference returns for getters to avoid copies
  • Accept % copy parameters for small values like integers
  • Accept & reference parameters for large read-only data

Next Steps

Learn about generics to create reusable class templates, or explore lambdas for functional programming.