Independent Instances
Part of the Object Oriented Programming section of Coddy's Lua journey — lesson 10 of 70.
A crucial aspect of object-oriented programming is that each instance maintains its own separate state. When you create two objects from the same class, they are completely independent—changing one does not affect the other.
Consider this example:
local Counter = {}
Counter.__index = Counter
function Counter:new(start)
local instance = {}
setmetatable(instance, self)
instance.value = start or 0
return instance
end
function Counter:increment()
self.value = self.value + 1
end
-- Create two separate counters
local counterA = Counter:new(10)
local counterB = Counter:new(5)
counterA:increment()
counterA:increment()
print(counterA.value) -- Output: 12
print(counterB.value) -- Output: 5Even though both counters come from the same Counter class, incrementing counterA has no effect on counterB. Each object has its own value field stored in its own instance table.
This independence is what makes objects useful. You can create dozens of players in a game, each tracking their own health and score. You can manage multiple bank accounts, each with a different balance.
The class defines the structure and behavior, but each instance lives its own life with its own data.
Challenge
EasyLet's prove that objects from the same class truly live independent lives! You'll build a Wallet class and create two separate wallet instances, then modify them independently to demonstrate that changes to one don't affect the other.
You'll organize your code across two files:
Wallet.lua: Define yourWalletclass with the standard constructor pattern. Each wallet should track its ownbalance. Include:- A
:new(startingBalance)constructor that initializes the wallet with the given amount - An
:add(amount)method that increases the balance - A
:spend(amount)method that decreases the balance
- A
main.lua: Require your Wallet module and create two separate wallet instances. Perform different operations on each to show they maintain independent state.
You will receive four inputs:
- Starting balance for wallet A
- Starting balance for wallet B
- Amount to add to wallet A
- Amount to spend from wallet B
In your main file:
- Create
walletAwith the first starting balance - Create
walletBwith the second starting balance - Add the specified amount to
walletA - Spend the specified amount from
walletB - Print both balances on separate lines
Print the final balances in this exact format:
Wallet A: [balance]
Wallet B: [balance]For example, if the inputs are 100, 50, 25, and 10, the output should be:
Wallet A: 125
Wallet B: 40Notice how adding to wallet A doesn't change wallet B, and spending from wallet B doesn't affect wallet A—each instance maintains its own separate balance.
Cheat sheet
Each instance of a class maintains its own separate state. Creating multiple objects from the same class results in completely independent instances—modifying one does not affect the others.
Example demonstrating instance independence:
local Counter = {}
Counter.__index = Counter
function Counter:new(start)
local instance = {}
setmetatable(instance, self)
instance.value = start or 0
return instance
end
function Counter:increment()
self.value = self.value + 1
end
-- Create two separate counters
local counterA = Counter:new(10)
local counterB = Counter:new(5)
counterA:increment()
counterA:increment()
print(counterA.value) -- Output: 12
print(counterB.value) -- Output: 5Each object has its own instance table storing its own data. The class defines the structure and behavior, but each instance maintains independent state.
Try it yourself
-- Require the Wallet module
local Wallet = require('Wallet')
-- Read inputs
local startingA = tonumber(io.read())
local startingB = tonumber(io.read())
local addAmount = tonumber(io.read())
local spendAmount = tonumber(io.read())
-- TODO: Create walletA with the first starting balance
-- TODO: Create walletB with the second starting balance
-- TODO: Add the specified amount to walletA
-- TODO: Spend the specified amount from walletB
-- TODO: Print the final balances in the required format
-- Format: "Wallet A: [balance]" and "Wallet B: [balance]"
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