Manuale di riferimento MALDA™

Il linguaggio di programmazione AI-First - Versione 1.0.11

11. Classi e oggetti

Una classe è un tipo con nome, campi (stato) e metodi (comportamento). new ClassName(...) esegue il costruttore e restituisce un'istanza. Stesso file: Examples/OOP/classes_objects.malda.

11.1 Una classe funzionante

Il costruttore ha lo stesso nome della classe. Usa this.field quando un parametro nasconde un campo; altrove l'accesso ai membri può essere implicito. I metodi sono funzioni dichiarate dentro la classe.

class Person {
    public var name;
    public var age;

    function Person(name, age) {
        this.name = name;
        this.age = age;
    }

    public function introduce() {
        print("Hi, I'm " + name + " and I'm " + string(age) + " years old.");
    }

    public function getAge() {
        return age;
    }

    public function setAge(newAge) {
        age = newAge;
    }
}

var person1 = new Person("Alice", 30);
var person2 = new Person("Bob", 25);
person1.introduce();
person2.introduce();
print("Alice's age: " + string(person1.getAge()));
person1.setAge(31);
print("Alice's new age: " + string(person1.getAge()));
Non chiamare new Person(...) se class Person non è dichiarata nello stesso programma (o importata). Uno snippet che mostra solo new Person non è un esempio completo.

11.2 Modificatori di accesso

11.3 Ereditarietà

Una classe può estendere un solo padre con extends. Chiama super(...) dal costruttore figlio, e super.method() per riusare un metodo del padre. Stesso file: Examples/OOP/inheritance.malda.

class Animal {
    public var name;

    function Animal(name) {
        this.name = name;
    }

    public function speak() {
        print(name + " makes a sound");
    }
}

class Dog extends Animal {
    function Dog(name) {
        super(name);
    }

    public function speak() {
        print(name + " says: Woof!");
    }
}

class Cat extends Animal {
    function Cat(name) {
        super(name);
    }

    public function speak() {
        print(name + " says: Meow!");
    }
}

var dog = new Dog("Rex");
var cat = new Cat("Fluffy");
dog.speak();
cat.speak();

Per eseguire anche l'implementazione del padre, chiama super.speak() dentro l'override prima o dopo il corpo del figlio.

11.4 Membri static

I membri static appartengono alla classe, non alle istanze:

class MathUtils {
    static var PI = 3.14159;

    static function add(a, b) {
        return a + b;
    }
}

var pi = MathUtils.PI;
var sum = MathUtils.add(5, 3);

11.5 Overload degli operatori

Le classi possono fare overload di operatori selezionati definendo metodi con nomi riservati. Per gli operatori binari, MALDA prova prima l'overload dell'operando sinistro (__add__, __sub__, ecc.). Se quell'overload non c'è, prova l'overload invertito dell'operando destro (__radd__, __rsub__, ecc.) passando l'operando sinistro come argomento. Per gli operatori unari, l'unico operando è il receiver.

OperatoreMetodo dell'operando sinistroMetodo di fallback dell'operando destro
+__add__(other)__radd__(other)
- (binario)__sub__(other)__rsub__(other)
*__mul__(other)__rmul__(other)
/__div__(other)__rdiv__(other)
%__mod__(other)__rmod__(other)
==__eq__(other)__req__(other)
!=__neq__(other)__rneq__(other)
<__lt__(other)__rlt__(other)
<=__le__(other)__rle__(other)
>__gt__(other)__rgt__(other)
>=__ge__(other)__rge__(other)
- (unario)__neg__()n/a

Se non esiste un metodo di overload corrispondente né a sinistra né a destra, MALDA usa il comportamento built-in dell'operatore.

class Value {
    public var data;

    function Value(data) {
        this.data = data;
    }

    public function __add__(other) {
        return data + other.data;
    }
}

var a = new Value(2);
var b = new Value(3);
print(a + b); // 5
class RightValue {
    public var data;

    function RightValue(data) {
        this.data = data;
    }

    public function __radd__(other) {
        return other + data;
    }
}

var rhs = new RightValue(7);
print(5 + rhs); // 12

11.6 Costruttori primari

Una lista di parametri dopo il nome della classe è un costruttore primario. Ogni parametro diventa un campo public con lo stesso nome, e MALDA sintetizza un costruttore che assegna quei campi. Il corpo opzionale è un corpo di classe normale (metodi, campi extra, membri static, overload degli operatori). Non c'è una keyword aggiuntiva: class Name( è distinto da class Name { e da class Name extends.

Quelle forme si espandono in una classe classica: campi public, un costruttore con lo stesso nome della classe che assegna this.x = x (e così via), poi gli eventuali membri del corpo. I type hint opzionali sui parametri vengono memorizzati su quei campi: class Point(x: float, y: float).

class Point(x, y);
var p = new Point(3, 4);
print(p.x + p.y);
class Point(x, y) {
    function total() {
        return this.x + this.y;
    }
}
print(new Point(3, 4).total());

Vedi anche