📅  最后修改于: 2020-10-16 05:18:26             🧑  作者: Mango
面向对象编程(OOP)是现代编程时代中使用最广泛的编程技术之一。有许多支持OOP的编程语言,包括:
类-类是用于创建对象的可扩展模板,提供状态(成员变量)和行为实现的初始值。
对象-它是类的实例,并为其分配了单独的内存。
继承-这是一个类的变量和函数被另一类继承的概念。
封装-这是将数据和函数合并到一个类中的过程。可以借助函数在类外部访问数据。也称为数据抽象。
您可以借助表和Lua的一流功能在Lua中实现面向对象。通过将函数和相关数据放入表中,可以形成一个对象。继承可以在元表的帮助下实现,它为父对象中不存在的函数(方法)和字段提供了一种查找机制。
Lua中的表具有对象(如状态和身份)的功能,而与对象的值无关。具有相同值的两个对象(表)是不同的对象,而一个对象在不同时间可以具有不同的值,但是它始终是同一对象。像对象一样,表的生命周期与创建对象或创建对象的位置无关。
面向对象的概念已被广泛使用,但是您需要清楚地理解它才能获得最大的收益。
让我们考虑一个简单的数学示例。我们经常遇到需要处理不同形状(例如圆形,矩形和正方形)的情况。
形状可以具有公共属性Area。因此,我们可以从具有公共属性区域的基础对象形状扩展其他形状。每个形状都可以具有自己的属性和功能,例如矩形可以具有属性长度,宽度,面积作为其属性以及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
继承是将简单的基础对象(例如形状)扩展为矩形,正方形等的过程。它在现实世界中经常用于共享和扩展基本属性和功能。
让我们看一个简单的类扩展。我们有一个如下所示的类。
-- 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
我们可以借助其他新方法借助metatables扩展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()
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
-- Creating an 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("The area of Rectangle is ",self.area)
end
-- Creating an object
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。