Having trouble with inheritance and OOP

So, I’m coming back to coding on Roblox and I’m trying to understand OOP and inheritance. Using an older tutorial ( All about Object Oriented Programming )

To my understanding, I should be able to have a Class called " Tool " which has its own properties and functions and by using inheritance I can inherit all those properties and functions + assign more to my subclass?

THE PROBLEM
I cannot seem to get the functions ( methods? ) of my subclass to actually show up. I can use functions from the main class ( tool ) but cannot use or reference any from the subclass ( pickaxe ) ?

Tool = {}
Tool.__index = Tool

function Tool.new(owner, durability, damage)
	local NewTool = {}
	setmetatable(NewTool, Tool)
	
	NewTool.Owner = owner
	NewTool.Durabiltiy = durability
	NewTool.Damage = damage
	
	
	return NewTool
end

function Tool:UseTool()
	print(5)
end

function Tool:ChangeValue(val)
	self.Owner = val
	print(self.Owner)
end

return Tool

I am pretty certain this is right, I’ve messed around with it a little and it seems to work.

local CreateTool = require(script.Parent)

local Pickaxe = {}
setmetatable(Pickaxe, CreateTool)
Pickaxe.__index = Pickaxe

function Pickaxe.new(owner, durability, damage)
	local NewPickaxe = {}
	setmetatable(NewPickaxe, Pickaxe)
	
	return NewPickaxe
end

function Pickaxe:CreatePart()
	print(3)
end

function Pickaxe:TestPart()
	print(4)
end

return Pickaxe

:CreatePart and :TestPart do not work, only :UseTool and :ChangeValue

This is where the trouble is I imagine, I’ve changed return NewPickaxe to return Pickaxe which has the effect of allowing me to use all the functions, but then this would cause other issues I’d imagine.

local Pickaxe = require(...)
NewPick = Pickaxe.new()
NewPick:FUNCTIONHERE

Where FUNCTIONHERE is, I only get functions from the main class and not from the pickaxe subclass

Edit: I should also mention, when trying to call one of those functions from the subclass I get the following error: " attempt to call missing method ‘TestPart’ of table "

1 Like

Have you tried creating a metatable that holds __index and setting Pickaxe to that one?

1 Like

I don’t really understand what you mean by this, could you provide some example code? Again I am still just trying to mess around with this style of coding.

1 Like

Yes.

local myObject = {}
local myObjectMetatable = {__index = myObject}
-- do this instead of myObject.__index = myObject

--later in the script when you create a new object from the constructor
setmetatable(myNewObject, myObjectMetatable)

I believe the issue is that you’re setting the metatable before doing Pickaxe.__index.

1 Like

Like this? if so I am still having the same issue


local Pickaxe = {}
local PickaxeMetaTable = {__index = Pickaxe}

function Pickaxe.new()
	local NewPickaxe = {}
	setmetatable(Pickaxe, PickaxeMetaTable)
	
	return NewPickaxe
end

return Pickaxe```
1 Like

Interesting. I believe it has something to do with the inheritance, but I’m not really good at inheriting systems. Here’s a guide on how to do it, but I’m not sure if I could help much further. If you find an answer, post it here.

(read post 18 for inheritance)

1 Like

It doesn’t look to me like you’re setting up your metatables incorrectly. Are you sure you’re requiring the right module (the pickaxe one)? I copied yours 1:1 and am not getting any issues.

1 Like

Hey I apologize for the delayed response, I’m not really sure of anything. Could you perhaps send me EXACTLY what you have copied? I will see if this works for me as well and note any differences.

1 Like

Even when using the exact code I provided 1:1 but changing out, adding etc the requires it still doesn’t work, could you provide me an example with the main script you used? Currently im using the following:

local CreateTool = require(script.Parent.CreateTool)
local Pickaxe = require(script.Parent.Pickaxe)

local NewPickaxe = Pickaxe.new()
NewPickaxe:METHODHERE

the problem is it has no methods for some reason ( functions? methods? same thing right? )

1 Like

After doing a little bit more testing, I think the issue may have to do with the constructor of subclass ( pickaxe ) or my main script not properly working, when trying to pass print in my constructor, nothing happens implying nothing has been constructed which would make sense why there are no functions?

1 Like

Yeah.

Pickaxe:

local CreateTool = require(script.Parent.Tool)

local Pickaxe = {}
setmetatable(Pickaxe, CreateTool)
Pickaxe.__index = Pickaxe

function Pickaxe.new(owner, durability, damage)
	local NewPickaxe = {}
	setmetatable(NewPickaxe, Pickaxe)

	return NewPickaxe
end

function Pickaxe:CreatePart()
	print(3)
end

function Pickaxe:TestPart()
	print(4)
end

return Pickaxe

Tool:

local Tool = {}
Tool.__index = Tool

function Tool.new(owner, durability, damage)
	local NewTool = {}
	setmetatable(NewTool, Tool)

	NewTool.Owner = owner
	NewTool.Durabiltiy = durability
	NewTool.Damage = damage


	return NewTool
end

function Tool:UseTool()
	print(5)
end

function Tool:ChangeValue(val)
	self.Owner = val
	print(self.Owner)
end

return Tool

Test script:

local pick = require(script.Pick)

local newPick = pick.new()

pick:CreatePart() -- ok
pick:ChangeValue(1) -- ok

I think the subclass script is written wrong anyway, I’ve fixed it but again am still getting the same error.


local Pickaxe = {}
Pickaxe.__index = Pickaxe
setmetatable(Pickaxe, CreateTool)

function Pickaxe.new(owner, durability, damage, heat)
	local Object = CreateTool.new(owner, durability, damage)
	setmetatable(Object, Pickaxe)
	
	Object.Heat =  heat
	
	return Object
end

function Pickaxe:CreatePart()
	print(self.Owner)
end

function Pickaxe:TestPart()
	print(4)
end

return Pickaxe```

the above should be correct as per the tutorial I was following.

also are you sure this is working correctly? I’ve tried to use it to test it myself and still encountering error? the three scripts are almost definitely requiring the right modules, with the current setup you just sent I can only use functions from within the tool module, none from the pickaxe module even though I am creating a pickaxe object which should have both right?

Any chance it’s a commit failure or something? I’m certain it’s working on my end. I’ll attach my setup

Script.rbxm (1.7 KB)

Okay another update maybe it is how I am requiring it? I’ve literally just renamed them to exactly how you have it setup and moved them into the same order and now it’s working, the way I had it setup was that I had my main script > Tool( Module ) > Pickaxe ( Module ) would this indented method cause issue?

also I am not 100% sure if it is fixed, as using pick.new() then enacting change on that is fine, but shouldnt I really be enacting change on newpick rather than pick.new?

Oh whoops you’re right, oversight on my end.

But even so, namecalling using newPick doesn’t create any errors.
image

local pick = require(script.Pick)

local newPick = pick.new()

newPick:CreatePart() -- ok
newPick:ChangeValue(1) -- ok

I just want to be certain- you’re talking about it erroring at runtime and not that autocomplete doesn’t show up for the methods, right?

Well I am mainly talking about auto complete but I was receiving errors during runtime originally, I will test again to ensure this is working. I found a correlation between it not showing the auto complete and an error.

Testing this confirms my prediction anyway, while I didn’t receive an error this time I just didn’t get any output from the following:

local pick = require(script.Pick)

local newPick = pick.new()
newPick:CreatePart()
newPick:UseTool()
pick:CreatePart()
pick:UseTool()

Error on my behalf - I should probably test more before commenting, had the script in the wrong area anyway which explains the lack of output. I am receiving outputs, will test further and update you shortly.

1 Like

Works! I appreciate the help a ton and this has given me insight into a major error of thinking when it comes to using the auto complete, testing my code and actually writing oop. I really appreciate the help. Marking solution now :)) @7z99

( I am still unsure why the modules wouldn’t require properly the way they were setup, but I’m sure it’s probably something simple i overlooked. )

1 Like