Polymorphism is a fundamental concept in object-oriented programming that allows objects of different types to be treated as objects of a common base type. In Lua, polymorphism can be achieved through the use of metatables and inheritance.
Lua doesn't have built-in support for classes or inheritance, but it provides powerful mechanisms to implement polymorphic behavior. The key to achieving polymorphism in Lua lies in its flexible nature and the use of Lua Metatables.
Metatables allow you to define how objects behave in various situations, including method calls. By leveraging metatables, you can create objects that respond to the same method names differently based on their type.
-- Base class
local Animal = {}
function Animal:new(name)
local obj = {name = name}
setmetatable(obj, self)
self.__index = self
return obj
end
function Animal:speak()
return "The animal makes a sound"
end
-- Derived class
local Dog = Animal:new()
function Dog:speak()
return self.name .. " barks"
end
-- Usage
local generic_animal = Animal:new("Generic")
local dog = Dog:new("Buddy")
print(generic_animal:speak()) -- Output: The animal makes a sound
print(dog:speak()) -- Output: Buddy barks
While Lua doesn't have native class-based inheritance, you can simulate it to achieve polymorphic behavior. This approach allows you to create a hierarchy of objects that share common methods but can override them as needed.
local function createClass(base)
local class = {}
class.__index = class
if base then
setmetatable(class, {__index = base})
end
function class:new(...)
local instance = setmetatable({}, class)
if instance.init then
instance:init(...)
end
return instance
end
return class
end
-- Base class
local Shape = createClass()
function Shape:init(name)
self.name = name
end
function Shape:area()
return "Area calculation not implemented for " .. self.name
end
-- Derived classes
local Circle = createClass(Shape)
function Circle:init(radius)
Shape.init(self, "Circle")
self.radius = radius
end
function Circle:area()
return math.pi * self.radius^2
end
local Rectangle = createClass(Shape)
function Rectangle:init(width, height)
Shape.init(self, "Rectangle")
self.width = width
self.height = height
end
function Rectangle:area()
return self.width * self.height
end
-- Usage
local shapes = {
Circle:new(5),
Rectangle:new(4, 6),
Shape:new("Unknown")
}
for _, shape in ipairs(shapes) do
print(shape.name .. " area: " .. shape:area())
end
Polymorphism in Lua, while not as straightforward as in class-based languages, offers powerful and flexible ways to create extensible and maintainable code. By mastering Lua Metatables and simulated inheritance, you can implement sophisticated polymorphic designs in your Lua programs.
For more advanced object-oriented concepts in Lua, explore Lua Classes and Objects and Lua Inheritance.