Simple OOP
by Panda
Today I've developed a small module that simplifies OOP. It's primarily targeted at beginner developers, and aims to be "more pythonic," and abstract away some of the Metatable code that newer developers might not be familiar with.
Along with the module, I've provided four code snippets. Two showcasing objects and inheritance using the module I've created, and another two showcasing what it would look like without using the module.
Is this worth continuing to develop, or does it seem like extra bloat? Please share your thoughts!
OOP With the Class Module:
local Class = require(game:GetService("ReplicatedStorage").Class)
-- Define a new class
local MyClass = Class() do
-- Constructor method
function MyClass:Init(name, age)
self.name = name
self.age = age
end
-- A sample method
function MyClass:DisplayInfo()
print("Name: " .. self.name .. ", Age: " .. self.age)
end
end
-- Instantiate the class
local obj = MyClass("John Doe", 30)
obj:DisplayInfo() -- Output: Name: John Doe, Age: 30
print(obj, getmetatable(obj))
OOP With the Class Module (Inheritance Example):
-- Extend MyClass to create MySubClass
local MySubClass = MyClass:Extend() do
-- Override the constructor method
function MySubClass:Init(name, age, grade)
-- Call the parent constructor using self.__super
self.__super.Init(self, name, age)
self.grade = grade
end
-- A sample method specific to MySubClass
function MySubClass:DisplayFullInfo()
print("Name: " .. self.name .. ", Age: " .. self.age .. ", Grade: " .. self.grade)
end
end
-- Instantiate the subclass
local subObj = MySubClass("Jane Doe", 25, "A")
subObj:DisplayFullInfo() -- Output: Name: Jane Doe, Age: 25, Grade: A
print(subObj, getmetatable(subObj))
And here's code that does the exact same thing, but without the module. I believe using the class module makes it simpler, but that's up for debate, and I'd like to hear your thoughts on it.
Regular OOP:
-- Define a new class
local MyClass = {}
MyClass.__index = MyClass
function MyClass.new(name, age)
local self = setmetatable({}, MyClass)
self.name = name
self.age = age
return self
end
function MyClass:DisplayInfo()
print("Name: " .. self.name .. ", Age: " .. self.age)
end
-- Instantiate the class
local obj = MyClass.new("John Doe", 30)
obj:DisplayInfo() -- Output: Name: John Doe, Age: 30
print(obj, getmetatable(obj))
Regular OOP (Inheritance Example):
-- Extend MyClass to create MySubClass
local MySubClass = {}
MySubClass.__index = MySubClass
setmetatable(MySubClass, MyClass)
function MySubClass.new(name, age, grade)
local self = setmetatable(MyClass.new(name, age), MySubClass)
self.grade = grade
return self
end
function MySubClass:DisplayFullInfo()
print("Name: " .. self.name .. ", Age: " .. self.age .. ", Grade: " .. self.grade)
end
-- Instantiate the subclass
local subObj = MySubClass.new("Jane Doe", 25, "A")
subObj:DisplayFullInfo() -- Output: Name: Jane Doe, Age: 25, Grade: A
print(subObj, getmetatable(subObj))
The Class Behind It
Finally, we have the actual module. It's relatively simple, and is only 21 lines of code at the moment. The model can be found here, however I've also attached the code snippet because of how short it is
local Class = {}
Class.__index = Class
function Class:Call(...)
local obj = setmetatable({}, self)
if obj.Init then
obj:Init(...)
end
return obj
end
function Class:Extend()
local cls = setmetatable({}, { __index = self, __call = self.Call })
cls.__index = cls
cls.__super = self
return cls
end
setmetatable(Class, { __call = Class.Extend })
return Class
Conclusion
If you've made it this far, I'd really appreciate your feedback! This is my first DevForum post, so if you'd like to nitpick the content and formatting, I'd highly appreciate any of that feedback. I hope you guys like the concept for this module, and if so, I'll continue developing it.