Objects
Object-oriented-programming (OOP) is a programming pattern that stores data and behaviors into "objects". An object is a state (properties or fields) combined with behaviors (usually methods).
OOP attempts to parallel the real-world in this way.
A dog object might have a .name. It might also have a :bark() method, or a :eat(food) method which affects its .hunger property.
Notice that this looks very similar to the way ROBLOX instances work. That's because the instances closely parallel the C++ code, which is very object-oriented.
Methods
Methods in Lua use :. It's just sugar -- dog:bark("arf") is the same thing as dog.bark(dog, "arf").
You can define methods normally:
function dog.bark(dog, message)
print(dog.name .. " says " .. message)
end
or by using a : and the implicit self parameter:
function dog:bark(message)
print(self.name .. " says " .. message)
end
Classes
A common (but not universal) aspect of object-oriented-programming is classes. A class of objects is a group of objects that are similar. For instance, there might be a class of animals, and a sub-class of dogs.
Usually, when you design OOP programs, you write the classes. The classes act like "blueprints" -- ways to make new objects.
Inheritance
A major component of classes is inheritance. A subclass (e.g. Dog) inherits from a superclass (e.g., Animal). That means that anything that can be done to the superclass can be done to the subclass.
For instance, in ROBLOX, BasePart provides things like .BrickColor and .Anchored, and :BreakJoints(), which subclasses like SpawnLocation can take advantage of.
Mutability = :(
A very common feature of OOP designs is mutation -- objects can change. Note that while this can be very convenient, it can also quickly make things messy. Immutable -- unchanging -- objects can be nice since they are more easily used in various ways.
OOP in Lua
You essentially have an object-oriented design if you follow these criteria (note: I am not advising you do this -- OOP isn't necessarily the best way to design, especially since Lua isn't really made for it)
- No global variables (except classes), no global functions (except constructors)
- Functions are always methods on objects
- Constructor functions which create new objects. They should return a newly constructed object.
It might look like this:
Dog = {}
function Dog:bark(message)
print(self.Name .. " says " .. message)
end
function Dog.new(name)
local obj = {Name = name}
obj.Bark = Dog.Bark
return obj
end
local dog = Dog.new("Jeffrey")
dog:Bark("arf")
If you added a lot more methods, writing the constructor would start to become inconvenient.
Instead of attaching each method to the object, you can use the __index metamethod to make obj look like a Dog:
function Dog.new(name)
local obj = {name = name}
setmetatable(obj, {__index = Dog})
return obj
end
If you want to do inheritance, it's as simple as setting the metatable of the class:
setmetatable(Dog, {__index = Animal})
Then if Animal had a swim method, our dog object could also :swim.
2 comments
Mutable objects make BlueTaslem sad.
But your answer makes me very happy.