Object-Oriented Programming in Lua
Object-Oriented Programming (OOP) is a widely popular programming paradigm.
The following programming languages support object-oriented programming:
- C++
- Java
- Objective-C
- Smalltalk
- C#
- Ruby
Object-Oriented Features
- 1) Encapsulation: The ability to encapsulate an entity's information, functionality, and responses into a single object.
- 2) Inheritance: Inheritance allows for the extension of a program without modifying the original code, preserving existing functionality while adding new features. This helps reduce redundant code and improves software development efficiency.
- 3) Polymorphism: The same operation applied to different objects can yield different interpretations and execution results. At runtime, methods in derived classes can be invoked through pointers to the base class.
- 4) Abstraction: Abstraction simplifies complex real-world problems by finding the most appropriate class definitions and explaining problems at the most suitable inheritance levels.
Object-Oriented in Lua
We know that objects consist of attributes and methods. In Lua, the basic structure is a table, so tables are used to describe object attributes.
Functions in Lua can represent methods. Thus, classes in Lua can be simulated using tables and functions.
Inheritance can be simulated using metatables (not recommended, as it suffices for basic object simulations).
Tables in Lua are, in a sense, objects themselves. Like objects, tables have states (member variables); they maintain independence from their values, representing different objects with different values; an object can have different values at different times but remains one object; similar to objects, the lifecycle of a table is independent of its creation context. Objects have member functions, and tables do too:
Account = {balance = 0}
function Account.withdraw(v)
Account.balance = Account.balance - v
end
This definition creates a new function and stores it in the withdraw field of the Account object. It can be called as follows:
Account.withdraw(100.00)
A Simple Example
The following simple class includes three properties: area, length, and breadth, with the printArea method used to print the computed result:
-- Meta class
Rectangle = {area = 0, length = 0, breadth = 0}
-- Derived class method new
function Rectangle:new(o, length, breadth)
o = o or {}
setmetatable(o, self)
self.__index = self
self.length = length or 0
self.breadth = breadth or 0
self.area = length * breadth
return o
end
-- Derived class method printArea
function Rectangle:printArea()
print("Rectangle area is ", self.area)
end
Creating an Object
Creating an object involves allocating memory for an instance of a class. Each class has its own memory and shares common data.
r = Rectangle:new(nil, 10, 20)
Accessing Properties
Class properties can be accessed using the dot (.) operator:
print(r.length)
Accessing Member Functions
Class member functions can be accessed using the colon (:) operator:
r:printArea()
Memory is allocated upon object initialization.
Complete Example
The following demonstrates a complete example of object-oriented programming in Lua:
-- Meta class
Shape = {area = 0}
-- Base class method new
function Shape:new(o, side)
o = o or {}
setmetatable(o, self)
self.__index = self
side = side or 0
self.area = side * side
return o
end
-- Base class method printArea
function Shape:printArea()
print("Area is ", self.area)
end
-- Create object
myshape = Shape:new(nil, 10)
myshape:printArea()
Executing the above program outputs:
Area is 100
Lua Inheritance
Inheritance involves an object using another object's attributes and methods, allowing for the extension of base class attributes and methods.
The following demonstrates a simple inheritance example:
-- Meta class
Shape = {area = 0}
-- Base class method new
function Shape:new(o, side)
o = o or {}
setmetatable(o, self)
self.__index = self
side = side or 0
self.area = side * side
return o
end
-- Base class method printArea
function Shape:printArea()
print("Area is ", self.area)
end
The Square object inherits from the Shape class:
Square = Shape:new()
-- Derived class method new
function Square:new(o, side)
o = o or Shape:new(o, side)
setmetatable(o, self)
self.__index = self
return o
end
Complete Example
The following example demonstrates inheritance by extending a derived class method while preserving the base class's member variables and methods:
-- Meta class
Shape = {area = 0}
-- Base class method new
function Shape:new(o, side)
o = o or {}
setmetatable(o, self)
self.__index = self
side = side or 0
self.area = side * side
return o
end
-- Base class method printArea
function Shape:printArea()
print("Area is ", self.area)
end
-- Create object
myshape = Shape:new(nil, 10)
myshape:printArea()
Square = Shape:new()
-- Derived class method new
function Square:new(o, side)
o = o or Shape:new(o, side)
setmetatable(o, self)
self.__index = self
return o
end
-- Derived class method printArea
function Square:printArea()
print("Square area is ", self.area)
end
-- Create object
mysquare = Square:new(nil, 10)
mysquare:printArea()
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
-- Derived class method printArea
function Rectangle:printArea()
print("Rectangle area is ", self.area)
end
-- Create object
myrectangle = Rectangle:new(nil, 10, 20)
myrectangle:printArea()
Executing the above code outputs:
Area is 100
Square area is 100
Rectangle area is 200
Function Overriding
In Lua, we can override base class functions by defining our own implementation in the derived class:
-- Derived class method printArea
function Square:printArea()
print("Square area ", self.area)
end