Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is inheritance in Lua prototype-based or class-based?

Lua is often described as having prototype-based inheritance (for example in this answer). However, the "Inheritance" section of "Programming in Lua" talks about "base class" and "superclass" - terms from class-based inheritance.

Which model, prototype-based or class-based, best describes how inheritance works in Lua?

like image 949
user200783 Avatar asked Feb 08 '23 02:02

user200783


2 Answers

Lua is prototype-based.

Technically, there is no class or inheritance or base class, super class in Lua. Lua has some tools like metatables to simulate classical OOP. The main reason that the PiL book uses these terms is to make it easier for the reader to understand.

If you like the language-lawyer way of describing the syntax, read the reference manual, you won't find these terms there.

like image 103
Yu Hao Avatar answered Feb 16 '23 02:02

Yu Hao


Lua has a prototype-based inheritance system. Let's first make sure we understand that Lua doesn't have classes and really every object is of the same type (table). To mimic the notion of a class, lua uses metatables to define a set of properties on the table that are not defined on the table itself. Two tables can share the same behavior, because we can "prototype" an object with a metatable.

table1 = {}
table2 = {}

behavior = {myfunction = function() return 10 end}

setmetatable(table1, behavior)
setmetatable(table2, behavior)

table1.myfunction()   --> 10
table2.myfunction()   --> 10

In this way, table1 and table2 have the same behaviors and can be thought of as having the same "class", even though we really just defined the same behavior on two different tables.

To create a notion of inheritance, there are many options. Personally, I like the idea of creating a metatable, and programmatically merging the fields on the metatables that I'd like to "derive" from. Then, using this new merged metatable we can set the metatable on our new object.

behavior_derived = {myNewFunction = function() return 20 end}

-- merge the base behavior in with our derived behavior
for k,v in pairs(behavior) do behavior_derived[k] = v end

a_derived = {}
b_derived = {}

setmetatable(a_derived, behavior_derived)
setmetatable(b_derived, behavior_derived)

a_derived.myfunction()      --> 10
a_derived.myNewFunction()   --> 20

b_derived.myfunction()      --> 10
b_derived.myNewFunction()   --> 20

This is the closest that Lua can get to deriving "class"es from others that I can think of.

like image 32
Frank Bryce Avatar answered Feb 16 '23 02:02

Frank Bryce