Lua - 表继承
在 Lua 中,我们可以使用 Table 来定义 class,正如我们在 Table as Objects 中所见。本章我们将探讨如何将 Lua Table 作为 Object 进行继承。
通过 new function 创建对象
Lua 提供了 metamethods 来扩展 table 的属性。__index 是其中一个特殊的 metamethod,我们可以用它来继承 table 的属性。例如,每当我们创建一个新对象时,可以将 metatable 设置为 self,并将 __index method 更新为 self,如下所示——
function Shape:new (o)
-- 如果未提供对象,则创建对象
o = o or {}
setmetatable(o, self)
self.__index = self
return o
end
让我们考虑一个形状场景,例如圆形、矩形和正方形。这些形状可以有一个共同属性 Area。因此,我们可以从基础对象 shape 扩展其他形状,并带有共同属性 area。每种形状可以有自己的属性和函数,例如矩形可以有 length、breadth、area 作为其属性,以及 printArea 和 calculateArea 作为其函数。
创建 Shape Class 作为 Base Class
-- Base Class
Shape = {
-- 共同的 area 属性
area = 0,
-- printArea 函数
printArea = function(self)
print("Area: ",self.area)
end
}
-- new 方法用于创建新对象
function Shape:new (o)
-- 如果未提供对象,则创建对象
o = o or {}
setmetatable(o, self)
self.__index = self
return o
end
创建 Rectangle Class 作为 Sub Class
-- 通过扩展 Shape class 创建 Rectangle 对象 Rectangle = Shape:new() -- Derived class 的 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
创建 Circle Class 作为 Sub Class
-- 通过扩展 Shape class 创建 Circle 对象 Circle = Shape:new() -- Derived class 的 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
创建 Square Class 作为 Sub Class
-- 通过扩展 Shape class 创建 Square 对象 Square = Shape:new() -- Derived class 的 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
示例 - 使用 Rectangle 作为 Subclass
以下是使用 Rectangle 继承 Shape class 的完整示例。我们创建 Rectangle 的一个实例并打印其面积。
main.lua
-- Base Class
Shape = {
-- 共同的 area 属性
area = 0,
-- computeArea 函数
getArea = function(self)
return self.area
end
}
-- new 方法用于创建新对象
function Shape:new (o)
-- 如果未提供对象,则创建对象
o = o or {}
setmetatable(o, self)
self.__index = self
return o
end
-- 通过扩展 Shape class 创建 Rectangle 对象
Rectangle = Shape:new()
-- Derived class 的 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
-- 创建 Rectangle 对象
rectangle = Rectangle:new(nil, 10, 5)
-- 打印矩形面积
print("Area of rectangle: ", rectangle:getArea())
输出
当上述代码构建并执行时,会产生以下结果——
Area of rectangle: 50
示例 - 使用 Square 作为子类
以下是使用 Square 继承 Shape class 的完整示例。我们创建了一个 Square 的实例并打印其面积。
main.lua
-- 基类
Shape = {
-- 公共面积属性
area = 0,
-- 计算面积函数
getArea = function(self)
return self.area
end
}
-- 创建新对象的新方法
function Shape:new (o)
-- 如果未提供对象,则创建对象
o = o or {}
setmetatable(o, self)
self.__index = self
return o
end
-- 通过扩展 Shape class 创建 Square 对象
Square = Shape: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
-- 创建 Square 对象
square = Square:new(nil, 10)
-- 打印正方形的面积
print("Area of square: ", square:getArea())
输出
当上述代码构建并执行时,它会产生以下结果 −
Area of square: 100
示例 - 使用 Circle 作为子类
以下是使用 Circle 继承 Shape class 的完整示例。我们创建了一个 Circle 的实例并打印其面积。
main.lua
-- 基类
Shape = {
-- 公共面积属性
area = 0,
-- 计算面积函数
getArea = function(self)
return self.area
end
}
-- 创建新对象的新方法
function Shape:new (o)
-- 如果未提供对象,则创建对象
o = o or {}
setmetatable(o, self)
self.__index = self
return o
end
-- 通过扩展 Shape class 创建 Circle 对象
Circle = Shape: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
-- 创建 Circle 对象
circle = Circle:new(nil, 10)
-- 打印圆的面积
print("Area of Circle: ", circle:getArea())
输出
当上述代码构建并执行时,它会产生以下结果 −
Area of Circle: 314.0