How to call subclass method from Inherited Parent Method?

I have a parent class, Question, that has a method Init(). This method calls Load(), which is defined in its subclasses. My Goal is to call Init() in subclasses, so it runs the Parent Class Init(), which then calls the Load() in the subclasses.

My problem is, that although the subclasses run Init() with the data of the subclass, it tries to call Load() in the parent class.

function QuestionClass:new(Folder:Folder,Answer:string)
	return setmetatable({Level = Folder.Parent.Name,Difficulty = Folder.Name,Answer =Answer,Debounce = DebounceModule.new(3),Folder = Folder},QuestionClass)	
end

function QuestionClass:Init()
	for _,v in pairs(self.Folder:GetChildren()) do
		if not v.Value.Value then
			self.Model = v
			print(getmetatable(self))
			self:Load(v)
			v.Value.Value = true
			break
		end
	end
	table.insert(QuestionClass.Questions,self)
end

The MetaTable shoes that there is a Load() method,

                    ["Load"] = "function",
                    ["__index"] =  ▶ {...},
                    ["new"] = "function"
                 }

but it errors, saying it cannot find it.

ServerStorage.MainModule:44: attempt to call missing method 'Load' of table

Here is the subclass:

function ImageQuestion.new(Folder:Folder,DecalId:string,Answer:string)
	local self = setmetatable(QuestionClass:new(Folder,Answer),ImageQuestion)
	self.DecalId =DecalId
	self:Init()
	return self
end

function ImageQuestion:Load(Part:Part)
	local Decal = Instance.new("Decal",Part)
	Decal.Texture = self.DecalId
end

I have tried putting a test class Load() of the parent class, and it runs instead of the subclasses.
This doesn’t make sense to me, as the metastable clearly shows it has a Load() method. Any help would be appreciated.

I found a workaround by doing

getmetatable(self)["Load"](self,v)

but I still feel that this is an ugly solution. Any other ways still apreciated

Can you show how you are setting up your inheritance? If you aren’t overwriting the function from the superclass in the subclass, your methods should still be accessible without getmetatable

Parent Class:

local QuestionClass = {}
QuestionClass.__index = QuestionClass
function QuestionClass:new(Folder:Folder,Answer:string)
	return setmetatable({Level = Folder.Parent.Name,Difficulty = Folder.Name,Answer =Answer,Debounce = DebounceModule.new(3),Folder = Folder},QuestionClass)	
end

Child Class:

local ImageQuestion = {}
ImageQuestion.__index = QuestionClass


function ImageQuestion.new(Folder:Folder,DecalId:string,Answer:string)
	local self = setmetatable(QuestionClass:new(Folder,Answer),ImageQuestion)
	self.DecalId =DecalId
	self:Init()
	return self
end

I see, assuming ImageQuestion inherits QuestionClass, you’d set up ImageQuestion like this:

local QuestionClass = require(path.to.question.class)

local ImageQuestion = setmetatable({}, QuestionClass)
ImageQuestion.__index = ImageQuestion

function ImageQuestion.new()
    local self = setmetatable(QuestionClass:new(), ImageQuestion)
    self:Init()
    -- ...

then you should be able to call ImageQuestion:Load(), as well as ImageQuestion:Init()

QuestionClass would be in a whole other module?

Depending on how your game is laid out, yeah. It could also just be the table that contains your QuestionClass constructor if it’s going to be in the same script, in which case you could omit the require call entirely

1 Like

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