Skip to content

Lua Advanced OOP Guide — Inheritance, Mixins, and Metaclass Patterns

DodaTech Updated 2026-06-28 2 min read

In this tutorial, you will learn about Lua Advanced OOP Guide. We cover key concepts, practical examples, and best practices to help you master this topic.

Lua advanced OOP builds on metatable-based prototypes to implement multiple inheritance through __index chains, mixins by copying methods from multiple sources, and metaclass patterns that treat classes as objects with their own methods.

Multiple Inheritance

local function createClass(...)
    local parents = {...}
    local cls = {}
    
    cls.__index = function(self, key)
        for _, parent in ipairs(parents) do
            local value = parent[key]
            if value ~= nil then
                cls[key] = value  -- cache for speed
                return value
            end
        end
        return nil
    end
    
    return cls
end

local Walker = {walk = function() print("walking") end}
local Talker = {talk = function() print("talking") end}
local Person = createClass(Walker, Talker)

local p = {}
setmetatable(p, Person)
p.walk()  --> walking
p.talk()  --> talking

Mixins

local Loggable = {
    log = function(self, msg)
        print("[" .. os.date() .. "] " .. msg)
    end
}

local Serializable = {
    serialize = function(self)
        return table.concat(
            {self.name, self.value},
            ","
        )
    end
}

local User = {name = "", value = 0}
for k, v in pairs(Loggable) do User[k] = v end
for k, v in pairs(Serializable) do User[k] = v end

Metaclass Pattern

local Class = {}

function Class:new(name)
    local obj = {name = name, methods = {}}
    obj.__index = obj.methods
    setmetatable(obj, self)
    self.__index = self
    return obj
end

function Class:method(name, func)
    self.methods[name] = func
end

function Class:create(...)
    local instance = {}
    setmetatable(instance, self)
    if instance.init then
        instance:init(...)
    end
    return instance
end

-- Usage
local Animal = Class:new("Animal")
Animal:method("speak", function(self)
    print(self.name .. " makes a sound")
end)

local dog = Animal:create()
dog.name = "Dog"
dog:speak()  --> Dog makes a sound

Common Mistakes

1. Circular inheritance

Ensure inheritance chains don't form loops. Lua will stack overflow on recursive __index.

2. Overriding methods unintentionally

Mixins can overwrite existing methods. Apply mixins in the correct order.

3. Forgetting to set __index

Without __index on the metatable, method lookup fails silently.

Practice Questions

1. How does Lua implement multiple inheritance? Through __index metamethods that search multiple parent tables sequentially.

2. What is a mixin? A set of methods copied into a class from separate source tables to compose functionality.

3. What does the metaclass pattern enable? Classes as objects that can create subclasses, have their own methods, and control instance creation.

FAQ

{{< faq question="Is there a built-in class system in Lua?" >}} No. Lua uses prototypes and metatables. Class systems are user-implemented patterns. {{< /faq >}}

{{< faq question="How do I call a parent method?" >}} Store the parent method reference before overriding: local parent_speak = Animal.speak; function Dog.speak(self) parent_speak(self); print("Woof!") end. {{< /faq >}}

{{< faq question="What is the performance cost of __index?" >}} Each failed lookup triggers __index. Cache resolved methods on the instance for repeated calls. {{< /faq >}}

What's Next

Now learn about weak tables.

Topic Description Link
Weak Tables Weak references and memory {{< ref "25-weak-tables" >}}
Garbage Collection GC control and tuning {{< ref "26-garbage-collection" >}}

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro