📜  Lua-面向对象

📅  最后修改于: 2020-10-16 05:18:26             🧑  作者: Mango


OOP简介

面向对象编程(OOP)是现代编程时代中使用最广泛的编程技术之一。有许多支持OOP的编程语言,包括:

  • C++
  • 爪哇
  • 物镜
  • 短暂聊天
  • C#
  • 红宝石

OOP的功能

  • -类是用于创建对象的可扩展模板,提供状态(成员变量)和行为实现的初始值。

  • 对象-它是类的实例,并为其分配了单独的内存。

  • 继承-这是一个类的变量和函数被另一类继承的概念。

  • 封装-这是将数据和函数合并到一个类中的过程。可以借助函数在类外部访问数据。也称为数据抽象。

Lua的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

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

继承完成示例

我们可以借助其他新方法借助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。