Lua - 面向对象

OOP简介

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

  • C ++

  • Java

  • Objective-C

  • Smalltalk

  • C#

  • Ruby

OOP的功能

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

  • 对象 &减去;它是类的一个实例,并为自己分配了单独的内存.

  • 继承 : 这是一个概念,通过该概念,一个类的变量和函数由另一个类继承.

  • 封装 : 它是在类中组合数据和函数的过程.借助功能可以在课外访问数据.它也被称为数据抽象.

Lua中的OOP

您可以实现面向对象在Lua的表和Lua的一流功能的帮助下.通过将函数和相关数据放入表中,形成对象.可以在metatables的帮助下实现继承,为不存在的函数(方法)和父对象中的字段提供查找机制.

Lua中的表具有对象的特征独立于其价值的国家和身份.具有相同值的两个对象(表)是不同的对象,而对象在不同的时间可以具有不同的值,但它始终是相同的对象.与对象一样,表的生命周期与创建它们的人或创建它们的位置无关.

真实示例

面向对象被广泛使用,但你需要清楚地理解它以获得适当和最大的好处.

让我们考虑一个简单的数学例子.我们经常遇到这样的情况:我们处理不同的形状,如圆形,矩形和方形.

形状可以有一个共同的属性Area.因此,我们可以使用公共属性区域从基础对象形状扩展其他形状.每个形状都可以有自己的属性,像矩形这样的函数可以有属性length,widthth,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


继承完成示例

我们可以延长如上所示,在另一个新方法的帮助下,在元数据的帮助下,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


在上面的例子中,我们创建了两个派生类 : 矩形和正方形从基类广场.可以在派生类中覆盖基类的函数.在此示例中,派生类将覆盖函数printArea.