Traits

A trait is a reusable set of fields and methods that a class can adopt. Traits let you share behavior across classes without forcing them into the same inheritance chain.

trait Damageable {
    Health = 100

    function TakeDamage(amount) {
        this.Health -= amount
    }

    function IsAlive() {
        return this.Health > 0
    }
}

class Enemy with Damageable {
}

local enemy = new Enemy()
enemy.TakeDamage(25)
print(enemy.Health)
print(enemy.IsAlive())

Keyword: with

For a class to use a trait, it uses the with keyword.

trait A {

}

class Base {

}

class Implementation : Base with A {

}

Required methods

A trait can provide an implementation for a function that can be overriden, yet if the function does not contain a body, then a class is required to implement the function.

trait Damageable {
    Health = 100

    // TakeDamage doesn't have a body, thus it's required to be implemented by a class
    function TakeDamage(amount)
}

class Enemy with Damageable {
    // If Enemy does not have this function, then a error will appear
    function TakeDamage(amount) {
        this.Health -= amount
    }
}

Multiple traits

It’s possible for a class to adopt multiple traits.

trait Named {
    Name = "Unknown"

    function PrintName() {
        print(this.Name)
    }
}

trait Damageable {
    Health = 100

    function TakeDamage(amount) {
        this.Health -= amount
    }
}

class Enemy with Named, Damageable {
}

local enemy = new Enemy()
enemy.Name = "Goblin"
enemy.PrintName()
enemy.TakeDamage(10)
print(enemy.Health)

Trait Inheritance

A trait can inherit another trait

trait Named {
    Name = "Unknown"

    function GetName() {
        return this.Name
    }
}

trait LoudNamed : Named {
    function PrintName() {
        print(this.GetName())
    }
}

class Enemy with LoudNamed {
}

Class override

If the class defines a method/field, then the class will override what is defined in the trait.

trait Greeter {
    function Greet() {
        print("Hello from trait")
    }
}

class NPC with Greeter {
    function Greet() {
        print("Hello from class")
    }
}

local npc = new NPC()
npc.Greet() // Hello from class

Categories:

Updated: