Menu
Coddy logo textTech

Calling Parent Methods

Part of the Object Oriented Programming section of Coddy's Lua journey — lesson 38 of 70.

Sometimes overriding a method completely isn't what you want. Instead, you might want to extend the parent's behavior—do what the parent does, then add something extra. To achieve this, you can call the parent method directly from within the child's override.

The technique uses dot syntax with the parent class name, explicitly passing self as the first argument:

local Animal = {}
Animal.__index = Animal

function Animal:new(name)
    local obj = {name = name}
    setmetatable(obj, Animal)
    return obj
end

function Animal:speak()
    print(self.name .. " makes a sound")
end

-- Dog extends the parent behavior
local Dog = {}
Dog.__index = Dog
setmetatable(Dog, {__index = Animal})

function Dog:new(name)
    local obj = Animal.new(Animal, name)
    setmetatable(obj, Dog)
    return obj
end

function Dog:speak()
    Animal.speak(self)  -- Call parent method first
    print(self.name .. " wags tail happily")
end

The key line is Animal.speak(self). By using dot syntax on the parent class and passing self manually, we invoke the original method before adding our own behavior:

local buddy = Dog:new("Buddy")
buddy:speak()
-- Output:
-- Buddy makes a sound
-- Buddy wags tail happily

This pattern is useful when the parent method does important work you don't want to duplicate. The child can run the parent's logic first, last, or even in the middle of its own code—giving you full control over how behaviors combine.

challenge icon

Challenge

Easy

Let's build a greeting system where a FormalPerson extends the behavior of a regular Person! Instead of completely replacing how a person introduces themselves, the formal version will first do the standard introduction, then add an extra polite touch.

You'll organize your code across three files:

  • Person.lua: Your base class with a :new(name) constructor that stores the person's name. Include an :introduce() method that prints the person's name followed by says hi. This is the base behavior that will be extended.
  • FormalPerson.lua: A child class that inherits from Person. Its constructor should call the parent constructor to handle the name. Override the :introduce() method, but instead of replacing the parent's behavior entirely, call the parent's method first using Person.introduce(self), then print an additional line with the person's name followed by bows politely.
  • main.lua: Require your FormalPerson module, read a name from input, create a FormalPerson instance, and call :introduce() to see both behaviors combined.

You will receive one input: the person's name.

When you call :introduce() on a FormalPerson, it should produce two lines of output—the first from the parent's method, the second from the child's addition:

{name} says hi
{name} bows politely

For example, if the input is Eleanor, the output should be:

Eleanor says hi
Eleanor bows politely

The key insight here is that FormalPerson doesn't duplicate the "says hi" logic—it delegates that work to the parent method, then adds its own unique behavior on top. This keeps your code clean and demonstrates how child classes can extend rather than replace parent functionality!

Cheat sheet

To extend a parent method's behavior instead of completely overriding it, call the parent method from within the child's override using dot syntax and explicitly passing self:

function ChildClass:method()
    ParentClass.method(self)  -- Call parent method
    -- Add additional behavior
end

Complete example showing method extension:

local Animal = {}
Animal.__index = Animal

function Animal:new(name)
    local obj = {name = name}
    setmetatable(obj, Animal)
    return obj
end

function Animal:speak()
    print(self.name .. " makes a sound")
end

local Dog = {}
Dog.__index = Dog
setmetatable(Dog, {__index = Animal})

function Dog:new(name)
    local obj = Animal.new(Animal, name)
    setmetatable(obj, Dog)
    return obj
end

function Dog:speak()
    Animal.speak(self)  -- Execute parent behavior first
    print(self.name .. " wags tail happily")  -- Add child behavior
end

local buddy = Dog:new("Buddy")
buddy:speak()
-- Output:
-- Buddy makes a sound
-- Buddy wags tail happily

The parent method can be called at any point: before, after, or in the middle of the child's own logic, giving full control over how behaviors combine.

Try it yourself

-- main.lua: Entry point for the greeting system

local FormalPerson = require('FormalPerson')

-- Read the person's name from input
local name = io.read()

-- TODO: Create a FormalPerson instance with the given name

-- TODO: Call the introduce method on the FormalPerson instance
quiz iconTest yourself

This lesson includes a short quiz. Start the lesson to answer it and track your progress.

All lessons in Object Oriented Programming