Lua - 面向对象
面向对象编程简介
面向对象编程 (OOP) 是现代编程时代最常用的编程技术之一。 有许多支持 OOP 的编程语言,包括,
- C++
- Java
- Objective-C
- Smalltalk
- C#
- Ruby
OOP 的特点
类 − 类是用于创建对象、为状态(成员变量)和行为实现提供初始值的可扩展模板。
对象 − 它是类的一个实例,并为自己分配了单独的内存。
继承 − 它是一个概念,一个类的变量和函数被另一个类继承。
封装 − 它是在一个类中组合数据和函数的过程。 在函数的帮助下,可以在类外访问数据。 它也被称为数据抽象。
Lua 中的 OOP
您可以借助 Lua 的表和一流的函数在 Lua 中实现面向对象。 通过将函数和相关数据放入表中,就形成了一个对象。 继承可以在元表的帮助下实现,为父对象中不存在的函数(方法)和字段提供查找机制。
Lua 中的表具有独立于其值的状态和身份等对象特性。 具有相同值的两个对象(表)是不同的对象,而一个对象可以在不同的时间具有不同的值,但它始终是同一个对象。 与对象一样,表的生命周期与创建者或创建位置无关。
现实世界的例子
面向对象的概念被广泛使用,但您需要清楚地理解它才能获得适当和最大的好处。
让我们考虑一个简单的数学示例。 我们经常会遇到处理不同形状的情况,例如圆形、矩形和正方形。
这些形状可以有一个共同的属性区域。 因此,我们可以使用公共属性区域从基础对象形状扩展其他形状。 每个形状都可以有自己的属性和功能,就像矩形可以有属性长度、宽度、面积作为它的属性和 printArea 和 calculateArea 作为它的功能。
创建一个简单的类
下面显示了具有三个属性区域、长度和宽度的矩形的简单类实现。 它还有一个 printArea 函数来打印计算出的面积。
-- 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("The area of Rectangle is ",self.area) end
创建对象
创建对象是为类实例分配内存的过程。 每个对象都有自己的内存并共享公共类数据。
r = Rectangle:new(nil,10,20)
访问属性
我们可以使用点运算符访问类中的属性,如下所示 −
print(r.length)
访问成员函数
您可以使用冒号运算符访问成员函数,对象如下所示 −
r:printArea()
分配内存并设置初始值。 初始化过程可以与其他面向对象语言中的构造函数进行比较。 它只不过是一个启用设置值的功能,如上所示。
完整示例
让我们看一个在 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("The area is ",self.area) end -- Creating an object myshape = Shape:new(nil,10) myshape:printArea()
当你运行上面的程序时,你会得到如下输出。
The area is 100
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("The area is ",self.area) end
我们可以将形状扩展为正方形类,如下所示。
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("The area of square is ",self.area) end
继承完整示例
我们可以在元表的帮助下借助另一个新方法来扩展 Lua 中的简单类实现,如上所示。 基类的所有成员变量和函数都保留在派生类中。
-- Meta class Shape = {area = 0} -- 基类方法 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 -- 基类方法 printArea function Shape:printArea () print("The area is ",self.area) end -- Creating an object myshape = Shape:new(nil,10) myshape:printArea() Square = Shape:new() -- 派生类方法 new function Square:new (o,side) o = o or Shape:new(o,side) setmetatable(o, self) self.__index = self return o end -- 派生类方法 printArea function Square:printArea () print("The area of square is ",self.area) end -- 创建对象 mysquare = Square:new(nil,10) mysquare:printArea() Rectangle = Shape:new() -- 派生类方法 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 -- 派生类方法 printArea function Rectangle:printArea () print("The area of Rectangle is ",self.area) end -- 创建对象 myrectangle = Rectangle:new(nil,10,20) myrectangle:printArea()
当我们运行上述程序时,我们将得到以下输出。−
The area is 100 The area of square is 100 The area of Rectangle is 200
在上面的例子中,我们创建了两个派生类 − 来自基类 Square 的 Rectangle 和 Square。 可以在派生类中覆盖基类的功能。 在此示例中,派生类覆盖函数 printArea。