SoFunction
Updated on 2025-04-12

A brief analysis of Lua object-oriented and inheritance

Table in Lua is an object, but if used directly, there will still be a lot of problems, as follows:

Copy the codeThe code is as follows:

 Account = {balance = 0}
 function (v)
     = - v
 end
--The following is the test call function
 (100.00)

The withdraw function above depends on the global variable Account internally. Once it changes, the withdraw will not work properly, such as:

Copy the codeThe code is as follows:

a = Account; Account = nil
(100.00)  --The error will cause access to empty nil.

This behavior clearly violates object-oriented encapsulation and instance independence. To solve this problem, we need to add another parameter self to the withdraw function, which is equivalent to this in java/C++, as follows:

Copy the codeThe code is as follows:

function (self,v)
     = - v
 end
--The following is a call based on the modified code:
 a1 = Account; Account = nil
(a1,100.00) --Working normally.

In response to the above problems, lua provides a more convenient syntax, which is to replace the point (.) with a colon (:), so that parameters can be hidden when defining and calling functions. like:

Copy the codeThe code is as follows:

 function Account:withdraw(v)
     = - v
 end
--The call code can be changed to:
 a:withdraw(100.00)

1. Category:

Lua does not provide object-oriented support in language, so if we want to implement this function, we can only simulate it through table, as follows:

Copy the codeThe code is as follows:

--The lovenumber here is a public member variable
Father={ lovenumber=0}

--new can be regarded as a constructor
function Father:new(p)
p=p or {}    --If no table is provided in the parameter, create an empty table
--Point the meta table of the new object instance to Father, so that Father can be used as a template
  setmetatable(p,self)
--Point Father's __index field to itself, so that the new object can be redirected when the specified key cannot be found, that is, access the key owned by Father
  self.__index=self
  return p
end

function Father:toString()
  print("I love my son!")
end

--Loving is considered a public member function
function Father:Loving(v)
=+v --The self here represents the instance object itself
   return
end

f1=Father:new{name="jianjian"}
f2=Father:new{name="baba",}
print(f1:Loving(100))
print(f2:Loving(200))
--Output answer
--100
--200

2. Inheritance

Inheritance is also a very important concept in object-oriented. In lua, we can also implement the inheritance mechanism like a mock class.

Copy the codeThe code is as follows:

Father={ lovenumber=0}

function Father:new(p)
  p=p or {}    
--Point the meta table of the new object instance to Father, so that Father can be used as a template
  setmetatable(p,self)
--Point Father's __index field to itself, so that the new object can be redirected when the specified key cannot be found, that is, access the key owned by Father
  self.__index=self
  return p
end

function Father:toString()
  print("I love my son!")
end

function Father:Loving(v)
   =+v
   return
end

--A subclass of Father is derived below. At this time, Son is still an object instance of Father
Son=Father:new()

--Rewrite the toString method in Father to implement custom functions
function Son:toString()
   print("I love myself!")
end


--When executing the following new method, the meta table of table s is already Son, not Father
s=Son:new()
print(s:toString()) --First find the method in the subclass Son
print(s:Loving(50)) --If there is no method in the subclass, the method in the parent class is called
--Output answer
--I love myself!
--50