Introduction to OOP
OOP (Object-oriented programming) is a style of computer programming that represents concepts as “objects” that have data fields (attributes that describe the object) and associated functions known as methods.
If you didn’t know that, this tutorial probably isn’t for you (this tutorial assumes at least some knowledge about OOP).
OOP in Lua
Lua does not have any OOP functionality, but one of its features – metatables – can be used to simulate OOP. A metatable in Lua is a table which describes another table (table-ception? no?)
Let’s Go!
Note: In this tutorial, I’ll be using Java terminology such as “class” and “constructor”. Just to clarify.
In this tutorial, we’ll be creating a “class” called Person, which has one field, name, three methods, getName(), setName(name) and toString(), and one constructor, new().
First off, we will define the Person “class”.
Person = {}
Person_mt = {}
Classes in Lua are represented by tables. The Person_mt table is a metatable which we will be using to describe the Person objects.Now, we will define the setName, getName and toString methods.
function Person.setName(self, newName)
self.name = newName
end
function Person.getName(self)
return self.name
end
function Person.toString(self)
return "Person object. name=" .. self.name
end
But wait! What’s this mysterious self variable? Don’t worry. All will become clear later.Now, we will define the the class constructor.
function Person.new()
local personObject = { name = "" }
setmetatable(personObject, Person_mt)
return personObject
end
Okay, seriously, what is going on here? Don’t worry. I’ll go through these bits once we’re finished.Finally, we need to set up the Person_mt metatable to do what we want.
Person_mt.__index = Person
At this point (after some reshuffling), the code looks like
Person = {}
Person_mt = {}
Person_mt.__index = Person
function Person.new()
local personObject = { name = "" }
setmetatable(personObject, Person_mt)
return personObject
end
function Person.getName(self)
return self.name
end
function Person.setName(self, newName)
self.name = newName
end
function Person.toString(self)
return "Person object. name=" .. self.name
end
Let’s go through this, section by section.Person_mt.__index = Person
Like I said before, a metatable is a table which describes a table. When I call a function or access a field of a table, Lua checks the __index field of the associated metatable. This line tells Lua that when I call personObject:something, it should go to the Person table and look up something.function Person.new()
local personObject = { name = "" }
setmetatable(personObject, Person_mt)
return personObject
end
This code defines a function new() within the Person table. Writing Person.new is the same as writing Person["new"]. Just a little syntactic sugar. Firstly, it creates a new table, personObject, with a name field. Then it tells Lua which metatable to use for the personObject table. Finally, it returns the personObject table which now acts as an object.function Person.getName(self)
return self.name
end
When we call this function, we can either call Person.getName(personObject) or personObject:getName(). Notice the colon instead of full-stop in the second call. This tells Lua to find the getName function in Person_mt.__index and pass personObject as the first parameter.The rest of the functions should be self-explanatory.
Now for some test code!
local personObject = Person:new()
personObject:setName("John")
print(personObject:toString())
Output:Person object. name=John
OOP Pro Tip
String objects are also defined in this way, so instead of writing string.sub(variable, 5) you can write variable:sub(5).
Thank you for reading to the end of my somewhat messy explanation. Please leave constructive criticism in the comments (replies, whatever).