Lua - Tables Inheritance



In Lua, we can define a class using Table as we've seen in Table as Objects. In this chapter we'll look at ways to inherit a Lua Table as an Object.

Object creation via new function

Lua provides metamethods to extend properties of a table. __index is one of the special metamethod which we can use to inherit properties of a table. For example, whenever we create a new object, we can set the metatable as self and update the __index method to self as well as shown below−

function Shape:new (o)
   -- create object if not provided
   o = o or {}   
   setmetatable(o, self)
   self.__index = self
   return o
end

Let's consider a scenario of shapes like circle, rectangle and square. The shapes can have a common property Area. So, we can extend other shapes from the base object shape with the common property area. Each of the shapes can have its own properties and functions like a rectangle can have properties length, breadth, area as its properties and printArea and calculateArea as its functions.

Create Shape Class as Base Class

-- Base Class
Shape = {
   -- common area property
   area = 0,
   
   -- printArea function   
   printArea = function(self)
      print("Area: ",self.area) 
   end
}

-- new method to create a new object
function Shape:new (o)
   -- create object if not provided
   o = o or {}   
   setmetatable(o, self)
   self.__index = self
   return o
end

Create Rectangle Class as Sub Class

-- create Rectangle object by extending Shape class
Rectangle = Shape:new()

-- Derived class method new
function Rectangle:new (o,length, breadth)
   o = o or Shape:new(o)
   setmetatable(o, self)
   self.__index = self
   self.area = length * breadth
   return o
end

Create Circle Class as Sub Class

-- create Circle object by extending Shape class
Circle = Shape:new()

-- Derived class method new
function Circle:new (o,radius)
   o = o or Shape:new(o)
   setmetatable(o, self)
   self.__index = self
   self.area = 3.14 * radius * radius
   return o
end

Create Square Class as Sub Class

-- create Square object by extending Shape class
Square = Shape:new()

-- Derived class method new
function Square:new (o,side)
   o = o or Shape:new(o)
   setmetatable(o, self)
   self.__index = self
   self.area = side * side
   return o
end

Example - Using Rectangle as Subclass

Following is the complete example of using Rectangle inheriting Shape class. We're creating a instance of Rectangle and printing its area.

main.lua

-- Base Class
Shape = {
   -- common area property
   area = 0,
   
   -- computeArea function   
   getArea = function(self)
      return self.area 
   end
}

-- new method to create a new object
function Shape:new (o)
   -- create object if not provided
   o = o or {}   
   setmetatable(o, self)
   self.__index = self
   return o
end

-- create Rectangle object by extending Shape class
Rectangle = Shape:new()

-- Derived class method new
function Rectangle:new (o,length, breadth)
   o = o or Shape:new(o)
   setmetatable(o, self)
   self.__index = self
   self.area = length * breadth
   return o
end

-- create object of Rectangle 
rectangle = Rectangle:new(nil, 10, 5)
-- print area of rectangle
print("Area of rectangle: ", rectangle:getArea())

Output

When the above code is built and executed, it produces the following result −

Area of rectangle: 	50

Example - Using Square as Subclass

Following is the complete example of using Square inheriting Shape class. We're creating a instance of Square and printing its area.

main.lua

-- Base Class
Shape = {
   -- common area property
   area = 0,
   
   -- computeArea function   
   getArea = function(self)
      return self.area 
   end
}

-- new method to create a new object
function Shape:new (o)
   -- create object if not provided
   o = o or {}   
   setmetatable(o, self)
   self.__index = self
   return o
end

-- create Square object by extending Shape class
Square = Shape:new()

-- Derived class method new
function Square:new (o,side)
   o = o or Shape:new(o)
   setmetatable(o, self)
   self.__index = self
   self.area = side * side
   return o
end

-- create object of Square 
square = Square:new(nil, 10)

-- print area of the square
print("Area of square: ", square:getArea())

Output

When the above code is built and executed, it produces the following result −

Area of square: 	100

Example - Using Circle as Subclass

Following is the complete example of using Circle inheriting Shape class. We're creating a instance of Circle and printing its area.

main.lua

-- Base Class
Shape = {
   -- common area property
   area = 0,
   
   -- computeArea function   
   getArea = function(self)
      return self.area 
   end
}

-- new method to create a new object
function Shape:new (o)
   -- create object if not provided
   o = o or {}   
   setmetatable(o, self)
   self.__index = self
   return o
end

-- create Circle object by extending Shape class
Circle = Shape:new()

-- Derived class method new
function Circle:new (o,radius)
   o = o or Shape:new(o)
   setmetatable(o, self)
   self.__index = self
   self.area = 3.14 * radius * radius
   return o
end

-- create object of Circle 
circle = Circle:new(nil, 10)

-- print area of the circle
print("Area of Circle: ", circle:getArea())

Output

When the above code is built and executed, it produces the following result −

Area of Circle: 	314.0
Advertisements