RBX docs Docs Idk

Inheritance

Pre-requisites

Before reading this tutorial, you should know about metatables. An explanation of metatables exists in the Lua-Learning folder (not anymore).

What is Inheritance?

Inheritance is used mainly in oop based languages that allow one class to inherit the properties and methods from another class.

*do note that there are a few ways of doing inheritance in lua(u) and this is one of them

Setting up Inheritance

Let’s say we have a class called Person Class that is set up like this

local Person = {}

Person.__index = Person

function Person.new(Name,Age,Balance)
   return setmetatable({Name = Name,Age = Age, Balance = Balance},Person)
end

function Person.__tostring(self)
    return self.Name
end
function Person:GetBalance()
    return '$'..self.Balance
end

function Person:GetAge()
    return self.Age
end

function Person:GrowUp()
    self.Age += 1
end

return Person

Now lets make a Class call Student that will inherit from the Person Class and give it a Method called PayStudentTuition

local Student = {}
local Person = require(Path.To.Person.Class)

Student.__index = setmetatable(Student,Person)

function Student.__tostring(self)
    return "Student: "..self.Name
end

function Student.new(Name,Age,Balance,Id)
	return setmetatable({Name = Name,Age = Age,Balance = Balance,Id = Id},Student)
end
--another way you can make the constructor
function Student.new(Name,Age,Balance,Id)
    local person = Person.new(Name,Age,Balance)
    person.Id = Id
    return setmetatable(person,Student)
end

function Student:PayStudentTuition(fees)
    self.Balance -= fees
end

return Student

Basically what we’ve done is modify the __index metamethod so it also checks the Person class if the method you’re looking for does not exist in the Student Class

For those that are wondering why we need to do it like that and we can’t just do this

local Student = {}
local Person = require(Path.To.Person.Class)

Student.__index = Student

function Student.new(Name,Age,Balance,Id)
   return setmetatable(setmetatable({Name = Name,Age = Age,Balance = Balance,Id = Id},Person),Student)
end

it’s because using setmetatable on a metatable will override the current metatable’s metamethods.

Now lets make a Class call Teacher that will inherit from the Person Class and give it a Method called GetPaycheck

local Teacher = {}
local Person = require(Path.To.Person.Class)

Teacher.__index = setmetatable(Teacher,Person)

function Teacher.__tostring(self)
    return "Teacher: "..self.Name
end

function Teacher.new(Name,Age,Balance)
    return setmetatable({Name = Name,Age = Age,Balance = Balance},Teacher)
end

function Teacher:GetPaycheck(Amt)
    self.Balance += Amt
end

return Teacher

Here is an example script

local StudentClass = require(Path.To.Student.Class)
local PersonClass = require(Path.To.Person.Class)
local TeacherClass = require(Path.To.Teacher.Class)
local Hao = PersonClass.new("Hao",nil,-99999)
local Bob = StudentClass.new("Bob",10,30,1235)
local Smith = TeacherClass.new("TeacherClass",37,200)

Bob:GrowUp() -- this is a method in the Person Class
Bob:PayStudentTuition(4000) -- this is a method in the Student Class
print(Bob:GetAge()) --> 11
print(Bob:GetBalance()) --> $-3970
print(Bob) -- Invokes the __tostring metamethod --> "Student: Bob"

Smith:GetPaycheck(100) -- this is a method in the Teacher Class
print(Smith:GetBalance()) --> $300
print(Smith) --> "Teacher: Smith"

print(Hao) --> "Hao"

Also if you want to inherit from multiple classes you would just keep adding to the __index metamethod

local MiddleSchoolStudent = {}

MiddleSchoolStudent.__index = setmetatable(MiddleSchoolStudent,Student)
-- will first check MiddleSchoolStudent then check Student and lastly it will check Person class if a key dose not exist

Thanks for reading!

Thats pretty much it for this method of inheritance. if you have any more questions you can ask in #scripting-help.