- Lua 教程
- Lua - 首页
- Lua 基础
- Lua - 概述
- Lua - 环境
- Lua - 基本语法
- Lua - 注释
- Lua - 打印 Hello World
- Lua - 变量
- Lua - 数据类型
- Lua - 运算符
- Lua - 循环
- Lua - 决策
- Lua - 函数
- Lua - 日期和时间
- Lua 数组
- Lua - 数组
- Lua - 多维数组
- Lua - 数组长度
- Lua - 遍历数组
- Lua 迭代器
- Lua - 迭代器
- Lua 列表
- Lua - 在列表中搜索
- Lua 模块
- Lua - 模块
- Lua - 命名空间
- Lua 元表
- Lua - 元表
- Lua 协程
- Lua - 协程
- Lua 文件处理
- Lua - 文件 I/O
- Lua 库
- Lua - 标准库
- Lua - 数学库
- Lua - 操作系统功能
- Lua 有用资源
- Lua - 快速指南
- Lua - 有用资源
- Lua - 讨论
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 中使用面向对象的完整示例。
main.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 中扩展上面显示的简单类实现,并使用另一种新方法。基类中的所有成员变量和函数都保留在派生类中。
main.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。