Inheriting Methods
Part of the Object Oriented Programming section of Coddy's Lua journey — lesson 32 of 70.
With the inheritance link established, child class instances automatically gain access to all parent methods. This happens through Lua's lookup chain—when you call a method on an instance, Lua searches through each connected table until it finds what you're looking for.
Consider this setup where Animal defines a :breathe() method:
local Animal = {}
Animal.__index = Animal
function Animal:new()
local obj = {}
setmetatable(obj, Animal)
return obj
end
function Animal:breathe()
print("Breathing...")
end
-- Dog inherits from Animal
local Dog = {}
Dog.__index = Dog
setmetatable(Dog, {__index = Animal})
function Dog:new()
local obj = {}
setmetatable(obj, Dog)
return obj
endNow watch what happens when we create a Dog and call the parent's method:
local buddy = Dog:new()
buddy:breathe() -- Output: Breathing...The Dog class never defined :breathe(), yet it works. Lua first checks buddy, finds nothing, then checks Dog, still nothing, and finally finds it in Animal. This automatic method inheritance means you write shared behavior once in the parent and every child class benefits immediately.
Challenge
EasyLet's build a simple creature hierarchy to see method inheritance in action! You'll create an Animal parent class and a Dog child class, then demonstrate that Dog instances can use methods defined only in Animal.
You'll organize your code across three files:
Animal.lua: Define your parent class with the standard class pattern. Include a:new(name)constructor that stores the animal's name, and a:speak()method that prints the animal's name followed bymakes a sound. Return the class at the end of the file.Dog.lua: Define your child class that inherits from Animal. Require the Animal module and set up the inheritance link so Dog can access Animal's methods. Include a:new(name)constructor that stores the name and sets Dog as the metatable. The Dog class should NOT define its own:speak()method—it will inherit this from Animal.main.lua: Require your Dog module, read a name from input, create a Dog instance with that name, and call the:speak()method on it.
You will receive one input: the dog's name.
For example, if the input is Buddy, the output should be:
Buddy makes a soundThe magic here is that your Dog class never defines :speak(), yet calling it on a Dog instance works perfectly. Lua follows the lookup chain from the Dog instance to the Dog class, then to the Animal class where it finds the method. This is inheritance at work!
Cheat sheet
Child class instances automatically gain access to all parent methods through Lua's lookup chain. When a method is called on an instance, Lua searches through each connected table until it finds the method.
Setting Up Inheritance
Parent class definition:
local Animal = {}
Animal.__index = Animal
function Animal:new()
local obj = {}
setmetatable(obj, Animal)
return obj
end
function Animal:breathe()
print("Breathing...")
endChild class with inheritance link:
local Dog = {}
Dog.__index = Dog
setmetatable(Dog, {__index = Animal})
function Dog:new()
local obj = {}
setmetatable(obj, Dog)
return obj
endUsing Inherited Methods
Child instances can call parent methods even if not defined in the child class:
local buddy = Dog:new()
buddy:breathe() -- Output: Breathing...The lookup chain: Lua checks buddy → Dog → Animal until the method is found.
Multi-File Class Organization
Parent class file (Animal.lua):
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
return AnimalChild class file (Dog.lua):
local Animal = require("Animal")
local Dog = {}
Dog.__index = Dog
setmetatable(Dog, {__index = Animal})
function Dog:new(name)
local obj = {name = name}
setmetatable(obj, Dog)
return obj
end
return DogMain file usage:
local Dog = require("Dog")
local buddy = Dog:new("Buddy")
buddy:speak() -- Output: Buddy makes a soundTry it yourself
-- main.lua: Entry point
local Dog = require('Dog')
-- Read the dog's name from input
local name = io.read()
-- TODO: Create a Dog instance with the given name
-- TODO: Call the :speak() method on the dog instance
This lesson includes a short quiz. Start the lesson to answer it and track your progress.
All lessons in Object Oriented Programming
1The 'Self' Concept
Tables with FunctionsExplicit 'self'The Colon SyntaxDot vs ColonRecap - Moving Point4Project: Digital Bank
Project SetupDeposit Method7Polymorphism & Overriding
Overriding MethodsCalling Parent MethodsDuck TypingCommon InterfaceChecking TypeRecap - Employee Roles10Project: Shape Manager
Project SetupRectangle Class2Class Prototype Pattern
The Prototype ConceptLinking with __indexThe :new() ConstructorInitializing AttributesIndependent InstancesRecap - Car Factory5Operator Overloading in OOP
Adding ObjectsSubtracting ObjectsConcatenating ObjectsComparing Objects (<, >)Recap - Wallet Math8Encapsulation
Naming ConventionsClosures for PrivacyAccess via ClosuresRead-Only TablesValidation LogicRecap - Secure Vault11Design Patterns (Lite)
Factory FunctionsSingleton TableIterator PatternObserver (Listener)Recap - Logger Factory3Object State and Behavior
Instance VariablesGetter MethodsSetter MethodsCalculated PropertiesFormatting StringsEquality ChecksRecap - Student Grade6Inheritance Basics
The Inheritance SetupInheriting MethodsExtending the ConstructorAdding Child MethodsShared vs UniqueRecap - Shape Hierarchy