Object Oriented Programming (Better than metatable OOP)
Tutorial difficulty: Advanced Begginer (no clue what does it mean)
This tutorial will be a mid-short summary about OOP method from: Tower - Roblox
Benefits:
-
More begginer friendly than metatable OOP.
-
faster than metatable OOP by like 10-100% (up to 2 times faster) (Results vary).
-
Easier to write types and don’t require any casting since it uses static types unlike metatable OOP.
-
More customization with metamethods (incase you need them).
-
Can contain multiple classes.
-
Ability to have same constructor for most of your classes.
-
Uses generic tables that don’t require any deep copy.
Cons:
In this tutorial we will learn:
- how to create a constructor
- how to add methods to constructor
- how to make a generic table
- how to create types and assign them to our generic table/constructor/method
For more advanced tutorial i would recomend you watching my video on this OOP approach:
Before doing anything lets set us a goals:
- Make a class Cat.
- Give class cat ability to print “Meow” via method “Meow”.
- Method that would print Text we input aswell as adding subtag with name of our cat in beggining of the message.
- Make class Cat include: Age of this cat and Name of this cat.
- Method that would tell us name and age of our class cat.
Part 1: Writing a Generic table
local Cat = {
Name="";
Age=0;
}
Part 2: Writing a constructor:
-- self shall be ignored as since calling methods will automatically pass 1st argument
--Source: https://create.roblox.com/docs/luau/functions#define-methods
function Constructor(self,Name,Age)
-- nelf is our newly created class!
local nelf = table.create(self)
-- will cast Name to string
nelf.Name = `{Name}`
-- will cast Age to number and if will fail then age will be 0
nelf.Age = tonumber(Age) or 0
-- returning our class
return nelf
}
local Cat = {
-- Referance to our constructor
new = Constructor;
Name="";
Age=0;
}
Part 3: Adding methods
-- self shall be ignored as since calling methods will automatically pass 1st argument
--Source: https://create.roblox.com/docs/luau/functions#define-methods
function Constructor(self,Name,Age)
-- nelf is our newly created class!
local nelf = table.create(self)
-- will cast Name to string
nelf.Name = `{Name}`
-- will cast Age to number and if will fail then age will be 0
nelf.Age = tonumber(Age) or 0
-- returning our class
return nelf
end
--Just a function, not an actual method
function Meow()
warn("Meow")
end
-- Upon calling it will say Name of our cat + text
function Say(self,text)
warn(`{self.Name}: {text}`)
end
function Info(self)
return self.Name,self.Age
end
local Cat = {
-- Referance to our constructor
new = Constructor;
-- Referance to function (could be used without : but . instead when calling)
Meow = Meow;
Say = Say;
Info = Info;
Name="";
Age=0;
}
Part 4: Adding types and description
--!strict
--!optimize 2
-- self shall be ignored as since calling methods will automatically pass 1st argument
--Source: https://create.roblox.com/docs/luau/functions#define-methods
--[[
if you see argument <strong>self</strong> after writing then you are doing smth wrong; Perhabs you used singular dot instead of : for method calling
<strong>Name</strong> Name of our cat
<strong>Age</strong> Age of our cat
]]
function Constructor(self:Cat,Name:string,Age:number): Cat
-- nelf is our newly created class!
local nelf = table.clone(self)
nelf.Name = Name
nelf.Age = Age
-- returning our class
return nelf
end
--Just a function, not an actual method
--[[
Can be called with singular dot aswell
A void function
]]
function Meow(): ()
warn("Meow")
end
-- Upon calling it will say Name of our cat + text
function Say(self:Cat,text:string): ()
warn(`{self.Name}: {text}`)
end
--[[Returns <strong>Tuple</strong> type that contains Name and Age of our cat]]
function Info(self:Cat): (string,number)
return self.Name,self.Age
end
local Cat:Cat = {
-- Referance to our constructor
new = Constructor;
-- Referance to function (could be used without : but . instead when calling)
Meow = Meow;
Say = Say;
Info = Info;
Name="";
Age=0;
}
-- Creating type for our cat
export type Cat = {
-- Methods
-- typeof does get what does function returns and description of function incase it has one
new:typeof(Constructor);
Meow:typeof(Meow);
Say:typeof(Say);
Info:typeof(Info);
-- Properties
Name:string;
Age:number;
}
Part 5: Usage
--!strict
--!optimize 2
-- self shall be ignored as since calling methods will automatically pass 1st argument
--Source: https://create.roblox.com/docs/luau/functions#define-methods
--[[
if you see argument <strong>self</strong> after writing then you are doing smth wrong; Perhabs you used singular dot instead of : for method calling
<strong>Name</strong> Name of our cat
<strong>Age</strong> Age of our cat
]]
function Constructor(self:Cat,Name:string,Age:number): Cat
-- nelf is our newly created class!
local nelf = table.clone(self)
nelf.Name = Name
nelf.Age = Age
-- returning our class
return nelf
end
--Just a function, not an actual method
--[[
Can be called with singular dot aswell
A void function
]]
function Meow(): ()
warn("Meow")
end
-- Upon calling it will say Name of our cat + text
function Say(self:Cat,text:string): ()
warn(`{self.Name}: {text}`)
end
--[[Returns <strong>Tuple</strong> type that contains Name and Age of our cat]]
function Info(self:Cat): (string,number)
return self.Name,self.Age
end
local Cat:Cat = {
-- Referance to our constructor
new = Constructor;
-- Referance to function (could be used without : but . instead when calling)
Meow = Meow;
Say = Say;
Info = Info;
Name="";
Age=0;
}
-- Creating type for our cat
export type Cat = {
-- Methods
-- typeof does get what does function returns and description of function incase it has one
new:typeof(Constructor);
Meow:typeof(Meow);
Say:typeof(Say);
Info:typeof(Info);
-- Properties
Name:string;
Age:number;
}
local ClassCat1 = Cat:new("Tiger",3)
ClassCat1.Meow()
ClassCat1:Say("Im a talking cat")
local Name,Age = ClassCat1:Info()
print(`Info: Age: {Age}, Name: {Name}`)
That whole tutorial.
You could do a lot of work arounds with this OOP method but i like this exact way of it becouse it keeps polymorphy just enough.
This is my first tutorial of that kind and i would like to hear suggestions as to how i can improve my future/this tutorial(s).