I am working with object oriented programming with Roblox but it's not working so well, I'm making a class/object called 'Automotive' and one called 'Motorcycle', Automotive has function like Start, Stop, and properties with Gas, Speed. Motorcycle is an Automotive but with a Killswitch, but when I use Motorcycle.new() it doesn't have Start or Stop, any help?
Automotive:
01 | local Automotive = { } |
02 | Automotive.__index = Automotive |
03 |
04 | Automotive.GasTank = 100 |
05 | Automotive.Speed = 100 |
06 |
07 | Automotive.new = function (modelNum) |
08 | local self = setmetatable ( { |
09 | ModelNumber = modelNum; |
10 | } , Automotive) |
11 | return self |
12 | end |
13 |
14 | function Automotive:Start() |
15 | print ( tostring (self.ModelNumber).. " started" ) |
Motorcycle:
01 | local Automotive = require(script.Parent.Automotive) |
02 |
03 | local Motorcycle = { } |
04 | Motorcycle.__index = Motorcycle |
05 |
06 | Motorcycle.new = function () |
07 | local NewMotorcycle = Automotive.new( tostring (math.random( 1 , 100000 ))) |
08 | local self = setmetatable (NewMotorcycle,Motorcycle) |
09 | return self |
10 | end |
11 |
12 | function Motorcycle:Killswitch() |
13 | print ( tostring (self.ModelNumber).. " used kill switch" ) |
14 | end |
15 |
16 | return Motorcycle |
Script:
1 | local Motorcycle = require(script.Parent.Motorcycle) |
2 | local vec 1 = Motorcycle.new() |
3 | vec 1 :Start() |
Error:
ServerScriptService.Script:3: attempt to call method 'Start' (a nil value)
Namaste it is i, dual
On a sidenote, what you're trying to do here is called inheritance. You're trying to get Motorcycle
, a subclass, to 'extend' or inherit from, a superclass - Automotive
. Just thought you should know what to Google, for the future.
Now, first of all, if you're going to use the function syntactic sugar in your code, I recommend keeping it up throughout. This means
1 | function Motorcycle.new() |
rather than
1 | Motorcycle.new = function () |
I don't usually do this, but your code was pissing me off so much I reformatted the whole thing. If you don't like my reformatting, there's a footnote at the bottom to what the whole problem was and how I fixed it.
Automotive:
01 | local Automotive = { } |
02 | Automotive.__index = Automotive |
03 |
04 | Automotive.GasTank = 100 -- These probably serve a purpose so I won't remove them. |
05 | Automotive.Speed = 100 |
06 |
07 | function Automotive.new(model_number) -- Reformatted constructor to fit function syntantic sugar the rest of code is following |
08 | return setmetatable ( { ModelNumber = model_number } , Automotive) -- Removed `self` variable, cut down on non-needed indents which were served the opposite of its purpose - didn't make code any clearer. |
09 | end |
10 |
11 | function Automotive:Start() |
12 | print (self.ModelNumber.. " started" ) -- Got rid of unnecessary `tostring()` |
13 | end |
14 |
15 | function Automotive:Stop() |
16 | print (self.ModelNumber.. " stopped" ) -- Same changes as `:Start()` |
17 | end |
18 |
19 | return Automotive |
Motorcycle:
01 | local Automotive = require(script.Parent.Automotive) |
02 |
03 | local Motorcycle = { } |
04 | Motorcycle.__index = Motorcycle |
05 | setmetatable (Motorcycle, Automotive) -- This is what your inquiry was. |
06 |
07 | function Motorcycle.new() -- Same changes as Automatice constructor |
08 | local NewMotorcycle = Automotive.new(math.random( 1 , 100000 )) -- Removed redundant `tostring()` |
09 | return setmetatable (NewMotorcycle,Motorcycle) |
10 | end |
11 |
12 | function Motorcycle:Killswitch() |
13 | print (self.ModelNumber.. " used kill switch" ) -- You probably know what I did, at this point |
14 | end |
15 |
16 | return Motorcycle |
You should look into WHY you do things, instead of just doing them.
In this case, the setmetatable(Motorcycle, Automotive)
is where we're faking the inheritance.
This works because you're virtually passing Automotive
's metamethods over to Motorcycle
.
It's the equivalent of doing setmetatable(Motorcycle, {__index = Automotive})
in your case. Which means you should be careful when using the former. As I said, it passes ALL the metamethods of Automotive
over, rather than just __index
. This means, as said before, it works specifically for your case (because you're only using the __index
method anyway), but you should keep this in mind.
You can read more on metamethods and their use here: https://developer.roblox.com/articles/Metatables You can read an introduction to OOP in ROBLOX here: https://devforum.roblox.com/t/all-about-object-oriented-programming/8585
That is all