Lua - 面向对象

  • 面向对象简介

    面向对象编程 (OOP) 是现代编程时代最常用的编程技术之一。有许多支持 OOP 的编程语言,其中包括,
    • C++
    • Java
    • Objective-C
    • Smalltalk
    • C#
    • Ruby
  • 面向对象的特点

    • Class − 类是用于创建对象、为状态(成员变量)和行为实现提供初始值的可扩展模板。
    • Objects - 它是类的一个实例,并为自己分配了单独的内存。
    • Inheritance − 一个类的变量和函数被另一个类继承的概念。
    • Encapsulation− 是在一个类中组合数据和函数的过程。在函数的帮助下,可以在类外访问数据。它也称为数据抽象。
  • Lua 中的面向对象编程

    您可以借助 Lua 的表和一级函数在 Lua 中实现面向对象。通过将函数和相关数据放入一个表中,就形成了一个对象。继承可以在元表的帮助下实现,为父对象中不存在的函数(方法)和字段提供查找机制。
    Lua 中的表具有对象的特征,如状态和身份,独立于其值。具有相同值的两个对象(表)是不同的对象,而一个对象在不同时间可以具有不同的值,但它始终是同一个对象。与对象一样,表的生命周期与创建者或创建地点无关。
  • 一个真实世界的例子

    面向对象的概念被广泛使用,但您需要清楚地理解它以获得适当和最大的好处。
    让我们考虑一个简单的数学示例。我们经常遇到处理不同形状的情况,例如圆形、矩形和正方形。
    形状可以有一个共同的属性区域。因此,我们可以使用公共属性区域从基础对象形状扩展其他形状。每个形状都可以有自己的属性和功能,就像矩形可以有属性长度、宽度、面积作为其属性,打印区域和计算区域作为其功能。
  • 创建一个简单的类

    具有三个属性区域、长度和宽度的矩形的简单类实现如下所示。它还有一个 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
    
    在上面的例子中,我们从基类 Square 创建了两个派生类 - Rectangle 和 Square。可以在派生类中覆盖基类的功能。在此示例中,派生类覆盖了函数 printArea。