How Do I inherit properties from base class in sub class module? (OOP)

For some reason when I try to create a unit in my OOP module its not inheriting the properties from the base class (Unit).
I’m creating it like this:

local subClass
    local unitModule = unitType.Name
    if script.Unit:FindFirstChild(unitModule) then
        subClass = require(script.Unit[unitModule])
    end
local unitObject = subClass.new(unitType, playerTeam, unitColor)

Then it will go into my warden subClass:

-- MODULE
local Warden = setmetatable({}, Unit)
----------------------------
Warden.__index = Warden

function Warden.new(unitType, unitTeam, unitColor)
    local self = setmetatable(Unit.new(), Warden)
    self:init()
    return self

Then it should call the baseclass to create the unit and inherit the created unit.

-- MODULE
local Unit = {}
----------------------------
Unit.__index = Unit

Unit.unitTypes = {
    prefabs:WaitForChild("PulseCannon"), 
    prefabs:WaitForChild("Warden"),
    prefabs:WaitForChild("Tower"),
}

function Unit.new(unitType, unitTeam, unitColor)
    local self = setmetatable({}, Unit)
    
    self.UnitType = unitType
    self.UnitTeam = unitTeam
    self.UnitColor = unitColor
    self.UnitObject = self:initializeUnitObject()
    self.Alerted = false
    self._Janitor = Janitor.new()
    self._Janitor:Add(self.UnitObject)
    self:OnDestroy()
    return self

But for some reason when I use a function from the base class like Unit:Alert() inside a Sub-Class like warden (like this Warden:Alert()) it will go into the unit module and call it, but when it tried to use Properties from the baseclass, it says it does not exist. I understand this is because I am passing the Warden as self and not the Unit, but it should still inherit the properties right?
image
image
image

Video of error:

External Media

The function Warden.new calls Unit.new, which creates a new table with the __index metamethod set to Unit. Then, the warden function actually overwrites the __index metamethod, setting it to the Warden class.

Instead, the Warden class itself should inherit from the Unit class, and the Unit.new function would just be overwriten.

Example:

-- unit.lua
local unit = {}
unit.__index = unit

function unit.new()
  return setmetatable({},unit)
end
-- warden.lua
local warden = unit.new() -- warden inherits from unit
warden.__index = warden

function warden.new() -- overwrite the .new function
  return setmetatable({},warden) -- create a completely new table
end

Hope this helps!

1 Like

Is initializeUnitObject actually returning anything?

Also shouldn’t you be passing unitType, unitTeam, unitColor to Unit.new as well? ie setmetatable(Unit.new(unitType, unitTeam, unitColor), Warden). I’m wondering if initializeUnitObject is returning early or returning nil in the case of those 3 args not being passed.

2 Likes

That seems kinda messed up because then you are calling unit.new() on load. Would think that doing what I did was correct as the constructor itself would make a new object of the base class, then overwrites its metatable.

UPDATE: The issue ended up being incredibly stupid and I lost my entire day to this but…
While the code is making a new warden, the table that encapsulates that data doesn’t actually have a name. I’m referring to it as self usually. What’s wrong however, is that I’m calling Warden:Alert() instead of self:Alert() I was passing the module table which holds the functions, NOT the table holding the properties. I feel so incredibly stupid. I can’t believe how I overlooked what I was doing especially since I iterated over it many times. I spent over 6 hours on this.
image

Thanks to those who replied, I appreciated your input considering I usually get ignored or insulted when asking for code help on the internet.

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.