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