欢迎来到个人简历网!永久域名:gerenjianli.cn (个人简历全拼+cn)
当前位置:首页 > 范文大全 > 实用文>Lua面向对象编程学习笔记

Lua面向对象编程学习笔记

2022-08-21 08:40:54 收藏本文 下载本文

“早晨失踪人员”通过精心收集,向本站投稿了9篇Lua面向对象编程学习笔记,以下是小编帮大家整理后的Lua面向对象编程学习笔记,欢迎大家分享。

Lua面向对象编程学习笔记

篇1:Lua面向对象编程学习笔记

这篇文章主要介绍了Lua面向对象编程学习笔记,本文讲解了Lua中实现类的例子、类之间继承的例子等内容,需要的朋友可以参考下

其实 Lua 中的 table 是一种对象,因为它跟对象一样,有其自己的操作方法:

代码如下:

Role = { hp = 100 }

function Role.addHp(hp)

Role.hp = Role.hp + hp

end

Role.addHp(50)

print(Role.hp)

上面代码创建了一个名为 Role 对象,并有一个 addHp 的方法,执行 “Role.addHp” 便可调用 addHp 方法,

不过上面对象 Role 是以全局变量的方式创建,会有一种“全局污染”的威胁,即变量 Role 在其他地方被重新赋值(例如被赋成 nil),对象里的属性或方法可能会面临被销毁或不能正常工作的情况。

对于这种问题,Lua 提供一种“接受者”的解决方法,即额外添加一个参数 self 来表示对象本身:

代码如下:

Role = { hp = 100 }

function Role.addHP(self, hp)

self.hp = self.hp + hp

end

r = Role

r.addHP(r, 50)

print(r.hp)

这样就不怕对象 Role 被“全局污染”,因为构造了一个子对象 r,并以参数的方式传入,以供其方法调用操作。

对于这种把对象本身以参数的方式传入对象方法里的写法,Lua 提供了一种更优雅的写法,把点号(.)替换为冒号(:),这样在方法定义或调用时,便可隐藏 self 参数。修改如下:

代码如下:

Role = { hp = 100 }

function Role:addHp(hp)

self.hp = self.hp + hp

end

r = Role

r:addHp(50)

print(r.hp)

上面的 “r.addHp(50)” 的写法等价于 “r.addHp(r, 50)”

Lua 没有类的概念,不过可以通过元表(metatable)来实现与原型 prototype 类似的功能,而 prototype 与类的工作机制一样,都是定义了特定对象行为。Lua 里的原型特性主要使用元表的 __index 事件来实现,这样当调用对象没定义的方法时,会向其元表的 __index 键(事件)查找。例如有 a 和 b 两个对象,想让 b 作为 a 的原型 prototype,只需要把 b 设置为 a 元表的 __index 值就行:

代码如下:

setmetatable(a, {__index = b})

这样,当对象 a 调用任何不存在的成员都会到对象 b 中查找,a 可以拥有或调用 b 的属性或方法,从某种意义上看,b 可以看作是一个类,a 是 b 的对象。

对于上面 Role 的例子,对象的创建可以用 __index 元方法来改写,这样新创建的对象就拥有和 Role 一样的属性和方法。

代码如下:

function Role:new(o)

o = o or {}

setmetatable(o, self)

self.__index = self

return o

end

当执行 “r = Role:new ” 创建一个对象时,r 将 Role 设置为自己的元表,那么调用 “r:addHp(50)” 的时候,会在 r 里查找 addHp 方法,如果没有找到,则会进一步搜索其元表的 __index,因此等价于:

代码如下:

getmetatable(r).__index.addHp(r, 50)

从上面的 Role:new 方法可以知道,Role 的 __index 在创建时被指定为 self,因此其实就是执行:

代码如下:

Role.addHp(R, 50)

完整的类例子:

代码如下:

Role = { hp = 100 }

function Role:new(o)

o = o or {}

setmetatable(o, self)

self.__index = self

return o

end

function Role:addHp(hp)

self.hp = self.hp + hp

end

r = Role:new()

r:addHp(50)

print(r.hp)

继承

Lua 里继承机制还是像实现类那样实现,

假如打算从类 Role 派生出一个子类 Priest,它有一个魔法属性值 mp,那么可以先从类 Role 构造一个 Priest,继承类 Role 的所有属性和方法:

代码如下:

Priest = Role:new()

虽然 Priest 是 Role 的一个实例,不过它具有类 Role 的所有属性和方法,其实也可以把它看做是从类 Role 派生出来的类,因此可以从类 Priest 继续 new 一个对象出来:

代码如下:

p = Priest:new({ mp = 100 })

上面实例 p 除了多出一个魔法属性值 mp 外,还继承类 Role 的所有属性和方法,当调用 “p.addHp” 方法时,Lua 在 p 中找不到 addHp 方法,会到 Priest 中找,在 Priest 中找不到,会到 Role 中找。

因此,想重定义从父类 Role 继承来的方法,在类 Priest 上定义即可。假如想重定义 addHp 方法:每次加血都要先判断魔法值够不够,如果够,则加血,并扣除一定的魔法值。修改如下:

代码如下:

function Priest:addHp(hp)

if self.mp >= 20 then

self.mp = self.mp - 20

self.hp = self.hp + hp

end

end

这样,当调用 “p:addHp” 时,Lua 会优化取类 Priest 定义的 addHp 方法。

篇2:Lua教程(十二):面向对象编程

这篇文章主要介绍了Lua教程(十二):面向对象编程,本文讲解了类、继承、私密性等面向对象编程知识,需要的朋友可以参考下

Lua中的table就是一种对象,但是如果直接使用仍然会存在大量的问题,见如下代码:

代码如下:

Account = {balance = 0}

function Account.withdraw(v)

Account.balance = Account.balance - v

end

--下面是测试调用函数

Account.withdraw(100.00)

在上面的withdraw函数内部依赖了全局变量Account,一旦该变量发生改变,将会导致withdraw不再能正常的工作,如:

代码如下:

a = Account; Account = nil

a.withdraw(100.00) --将会导致访问空nil的错误,

这种行为明显的违反了面向对象封装性和实例独立性。要解决这一问题,我们需要给withdraw函数在添加一个参数self,他等价于Java/C++中的this,见如下修改:

代码如下:

function Account.withdraw(self,v)

self.balance = self.balance - v

end

--下面是基于修改后代码的调用:

a1 = Account; Account = nil

a1.withdraw(a1,100.00) --正常工作。

针对上述问题,Lua提供了一种更为便利的语法,即将点(.)替换为冒号(:),这样可以在定义和调用时均隐藏self参数,如:

代码如下:

function Account:withdraw(v)

self.balance = self.balance - v

end

--调用代码可改为:

a:withdraw(100.00)

1. 类:

Lua在语言上并没有提供面向对象的支持,因此想实现该功能,我们只能通过table来模拟,见如下代码及关键性注释:

代码如下:

--[[

在这段代码中,我们可以将Account视为class的声明,如Java中的:

public class Account

{

public float balance = 0;

public Account(Account o);

public void deposite(float f);

}

--]]

--这里balance是一个公有的成员变量。

Account = {balance = 0}

--new可以视为构造函数

function Account:new(o)

o = o or {} --如果参数中没有提供table,则创建一个空的。

--将新对象实例的metatable指向Account表(类),这样就可以将其视为模板了。

setmetatable(o,self)

--在将Account的__index字段指向自己,以便新对象在访问Account的函数和字段时,可被直接重定向。

self.__index = self

--最后返回构造后的对象实例

return o

end

--deposite被视为Account类的公有成员函数

function Account:deposit(v)

--这里的self表示对象实例本身

self.balance = self.balance + v

end

--下面的代码创建两个Account的对象实例

--通过Account的new方法构造基于该类的示例对象。

a = Account:new()

--[[

这里需要具体解释一下,此时由于table a中并没有deposite字段,因此需要重定向到Account,

同时调用Account的deposite方法。在Account.deposite方法中,由于self(a对象)并没有balance

字段,因此在执行self.balance + v时,也需要重定向访问Account中的balance字段,其缺省值为0。

在得到计算结果后,再将该结果直接赋值给a.balance。此后a对象就拥有了自己的balance字段和值。

下次再调用该方法,balance字段的值将完全来自于a对象,而无需在重定向到Account了。

--]]

a:deposit(100.00)

print(a.balance) --输出100

b = Account:new()

b:deposit(200.00)

print(b.balance) --输出200

2. 继承:

继承也是面向对象中一个非常重要的概念,在Lua中我们仍然可以像模拟类那样来进一步实现面向对象中的继承机制,见如下代码及关键性注释:

代码如下:

--需要说明的是,这段代码仅提供和继承相关的注释,和类相关的注释在上面的代码中已经给出。

Account = {balance = 0}

function Account:new(o)

o = o or {}

setmetatable(o,self)

self.__index = self

return o

end

function Account:deposit(v)

self.balance = self.balance + v

end

function Account:withdraw(v)

if v > self.balance then

error(“Insufficient funds”)

end

self.balance = self.balance - v

end

--下面将派生出一个Account的子类,以使客户可以实现透支的功能,

SpecialAccount = Account:new() --此时SpecialAccount仍然为Account的一个对象实例

--派生类SpecialAccount扩展出的方法。

--下面这些SpecialAccount中的方法代码(getLimit/withdraw),一定要位于SpecialAccount被Account构造之后。

function SpecialAccount:getLimit()

--此时的self将为对象实例。

return self.limit or 0

end

--SpecialAccount将为Account的子类,下面的方法withdraw可以视为SpecialAccount

--重写的Account中的withdraw方法,以实现自定义的功能。

function SpecialAccount:withdraw(v)

--此时的self将为对象实例。

if v - self.balance >= self:getLimit() then

error(“Insufficient funds”)

end

self.balance = self.balance - v

end

--在执行下面的new方法时,table s的元表已经是SpecialAccount了,而不再是Account。

s = SpecialAccount:new{limit = 1000.00}

--在调用下面的deposit方法时,由于table s和SpecialAccount均未提供该方法,因此访问的仍然是

--Account的deposit方法。

s:deposit(100)

--此时的withdraw方法将不再是Account中的withdraw方法,而是SpecialAccount中的该方法。

--这是因为Lua先在SpecialAccount(即s的元表)中找到了该方法。

s:withdraw(200.00)

print(s.balance) --输出-100

3. 私密性:

私密性对于面向对象语言来说是不可或缺的,否则将直接破坏对象的封装性。Lua作为一种面向过程的脚本语言,更是没有提供这样的功能,然而和模拟支持类与继承一样,我们仍然可以在Lua中通过特殊的编程技巧来实现它,这里我们应用的是Lua中的闭包函数。该实现方式和前面两个示例中基于元表的方式有着很大的区别,见如下代码示例和关键性注释:

代码如下:

--这里我们需要一个闭包函数作为类的创建工厂

function newAccount(initialBalance)

--这里的self仅仅是一个普通的局部变量,其含义完全不同于前面示例中的self。

--这里之所以使用self作为局部变量名,也是为了方便今后的移植。比如,以后

--如果改为上面的实现方式,这里应用了self就可以降低修改的工作量了。

local self = {balance = initialBalance} --这里我们可以将self视为私有成员变量

local withdraw = function(v) self.balance = self.balance - v end

local deposit = function(v) self.balance = self.balance + v end

local getBalance = function() return self.balance end

--返回对象中包含的字段仅仅为公有方法。事实上,我们通过该种方式,不仅可以实现

--成员变量的私有性,也可以实现方法的私有性,如:

--local privateFunction = function() --do something end

--只要我们不在输出对象中包含该方法的字段即可。

return {withdraw = withdraw, deposit = deposit, getBalance = getBalance}

end

--和前面两个示例不同的是,在调用对象方法时,不再需要self变量,因此我们可以直接使用点(.),

--而不再需要使用冒号(:)操作符了。

accl = newAccount(100.00)

--在函数newAccount返回之后,该函数内的“非局部变量”表self就不再能被外部访问了,只能通过

--该函数返回的对象的方法来操作它们。

accl.withdraw(40.00)

print(acc1.getBalance())

事实上,上面的代码只是给出一个简单的示例,在实际应用中,我们可以将更多的私有变量存放于上例的局部self表中。

篇3:Lua模拟面向对象示例

本文这里主要给大家分享的是一则使用Lua模拟面向对象的方法的示例代码,大家学习下思路,希望对大家能够有所帮助,

代码很简单,这里就不多废话了,大家主要看看思路

代码如下:

function class(super)

local mt = {__call = function(_c, ...)

local function create(_c, _o, ...)

if _c.__super then create(_c.__super, _o, ...) end

if _c.__ctor then _c.__ctor(_o, ...) end

return _o

end

local _o = create(_c, {}, ...)

return setmetatable(_o, _c)

end}

mt.__index = super or mt

return setmetatable({__super = super}, mt)

end

----------------------------------------------------------------------

A = class

function A:__ctor(s)

self.i = 123

self.j = 333

print(‘A ctor‘, s)

end

local a = A(‘a‘)

print(a.i, a.j)

-- B继承A

B = class(A)

function B:__ctor(s)

self.i = 444

print(‘B ctor‘, s)

end

local b = B(‘b‘)

print(b.i, b.j)

示例截图

以上就是本文的全部内容了,希望大家能够喜欢,

篇4:浅谈Lua的面向对象特性

这篇文章主要介绍了Lua的面向对象特性,包括对象和继承等传统OOP概念的几个关键知识点,需要的朋友可以参考下

面向对象的特性

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

对象: 它是类的实例并具有分配给自己独立的内存。

继承: 它是由变量和类的函数被其他类继承的概念。

封装: 它是将数据和函数相结合的一类内的方法。数据可以在类的外部与函数的帮助下进行访问。它也被称为数据抽象。

Lua的OOP

在Lua中实现面向对象与表和Lua的第一类函数。通过将函数和相关数据插入表中形成一个对象。继承可以在metatables的帮助下来实现,提供了一个查找机制不存在的函数(方法)和在父对象字段。

在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中一个完整的例子。

代码如下:

-- 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中我们可以扩展的简单类实现,如上图所示metatables另一个新的方法。所有的成员变量和基类的函数被保留在派生类。

代码如下:

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

在上面的例子中,我们创建了两个派生类Rectangle和Square从基类Square。因此能够在此改变基类的功能的派生类。在本实现例子中,派生类会取代函数printArea。

篇5:Lua模块与包学习笔记

这篇文章主要介绍了Lua模块与包学习笔记,本文讲解了加载模块、加载机制等内容,需要的朋友可以参考下

从 Lua 5.1 开始,Lua 加入了标准的模块管理机制,可以把一些公用的代码放在一个文件里,以API 接口的形式在其他地方调用,有利于代码的重用和降低代码耦合度,

创建模块

其实 Lua 的模块是由变量、函数等已知元素组成的 table,因此创建一个模块很简单,就是创建一个 table,然后把需要导出的常量、函数放入其中,最后返回这个 table 就行。格式如下:

代码如下:

-- 定义一个名为 module 的模块

module = {}

-- 定义一个常量

module.constant = “this is a constant”

-- 定义一个函数

function module.func1

io.write(“this is a public function!n”)

end

local function func2()

print(“this is a private function!”)

end

function module.func3()

func2()

end

return module

由上可知,模块的结构就是一个 table 的结构,因此可以像操作调用 table 里的元素那样来操作调用模块里的常量或函数。不过上面的 func2 声明为程序块的局部变量,即表示一个私有函数,因此是不能从外部访问模块里的这个私有函数,必须通过模块里的共有函数来调用。

最后,把上面的模块代码保存为跟模块名一样的 lua 文件里(例如上面是 module.lua),那么一个自定义的模块就创建成功。

加载模块

Lua 提供一个名为 require 的函数来加载模块,使用也很简单,它只有一个参数,这个参数就是要指定加载的模块名,例如:

代码如下:

require(“<模块名>”)

-- 或者是

-- require “<模块名>”

然后会返回一个由模块常量或函数组成的 table,并且还会定义一个包含该 table 的全局变量。

或者给加载的模块定义一个别名变量,方便调用:

代码如下:

local m = require(“module”)

print(m.constant)

m.func3()

加载机制

对于自定义的模块,模块文件不是放在哪个文件目录都行,函数 require 有它自己的文件路径加载策略,它会尝试从 Lua 文件或 C 程序库中加载模块,

require 用于搜索 Lua 文件的路径是存放在全局变量 package.path 中,当 Lua 启动后,会以环境变量 LUA_PATH 的值来初始这个环境变量。如果没有找到该环境变量,则使用一个编译时定义的默认路径来初始化。

当然,如果没有 LUA_PATH 这个环境变量,也可以自定义设置,在当前用户根目录下打开 .profile 文件(没有则创建,打开 .bashrc 文件也可以),例如把 “~/lua/” 路径加入 LUA_PATH 环境变量里:

代码如下:

#LUA_PATH

export LUA_PATH=“~/lua/?.lua;;”

文件路径以 “;” 号分隔,最后的 2 个 “;;” 表示新加的路径后面加上原来的默认路径。

接着,更新环境变量参数,使之立即生效:

代码如下:

source ~/.profile

这时假设 package.path 的值是:

代码如下:

/Users/dengjoe/lua/?.lua;./?.lua;/usr/local/share/lua/5.1/?.lua;/usr/local/share/lua/5.1/?/init.lua;/usr/local/lib/lua/5.1/?.lua;/usr/local/lib/lua/5.1/?/init.lua

那么调用 require(“module”) 时就会尝试打开以下文件目录去搜索目标

代码如下:

/Users/dengjoe/lua/module.lua;

./module.lua

/usr/local/share/lua/5.1/module.lua

/usr/local/share/lua/5.1/module/init.lua

/usr/local/lib/lua/5.1/module.lua

/usr/local/lib/lua/5.1/module/init.lua

如果找过目标文件,则会调用 package.loadfile 来加载模块。否则,就会去找 C 程序库。搜索的文件路径是从全局变量 package.cpath 获取,而这个变量则是通过环境变量 LUA_CPATH 来初始。搜索的策略跟上面的一样,只不过现在换成搜索的是 so 或 dll 类型的文件。如果找得到,那么 require 就会通过 package.loadlib 来加载它。

篇6:Lua table类型学习笔记

这篇文章主要介绍了Lua table类型学习笔记,本文讲解了table的基础知识和table库函数的使用以及面向对象编程实例,需要的朋友可以参考下

关系表类型,这是一个很强大的类型,我们可以把这个类型看作是一个数组。只是 C语言的数组,只能用正整数来作索引; 在Lua中,你可以用任意类型的值来作数组的索引,但这个值不能是 nil。同样,在C语言中,数组的内容只允许一种类型;在 Lua中,你也可以用任意类型的值来作数组的内容,nil也可以。

基本介绍

注意三点:

第一,所有元素之间,总是用逗号 “,” 隔开;

第二,所有索引值都需要用 “[”和“]” 括起来;如果是字符串,还可以去掉引号和中括号; 即如果没有[]括起,则认为是字符串索引

第三,如果不写索引,则索引就会被认为是数字,并按顺序自动从 1往后编;

例如:

代码如下:

tt = {“hello” ,33}

value = 4

tab = {[tt] = “table”,key = value, [“flag” ] = nil, 11}

print(tab[tt])

print(tab.key)

print(tab[1 ])

以上写法都是对的。

look = {[www] = “ok”}这样是不对的,www没有赋值,所以默认为nil因此出错table index is nil

代码如下:

---

temp = 1

tab = {[temp] = 1, 11}

print(tab[temp]) --此时的结果是11,因为11没有显式对应的key,因此从1开始,如果前面定义了,则覆盖其value

代码如下:

---

temp = 2

tab = {[temp] = 1, 11}

temp = 1

print(tab[temp]) -- 结果是11,虽然定义时[temp] = 1,但是后来我们改变了temp的值,所以指向另外的key了

以上可知:

1.对于字符串,在{}定义时,可以key = value, 也可以[“flag”] = nil,索引都是string类型,对于非nil类型变量(包括字符串),都可以[variable]=value的方式

2.使用table时,对于字符串,可以通过.的方式访问,也可以通过[]方式访问。tab[a],tab[b],只要a==b那么tab[a]可以访问到tab[b]的值

3.不管定义索引时用的是常量还是变量,最终table中value的索引key是常量,不会随变量的改变而变化该value的key

嵌套

代码如下:

tb11= {tb12 = {bool = true}} -- simple, it‘s a table IN a table :)

-- Call magic!

print(tb11.tb12.bool ) -- works fine, since it‘s calling the key and value correctly.

print(tab11[“tb12” ].bool ) --same as line 33

print(tab11.tb12 [“bool”]) --same as line 33

print(tab11[“tb12” ][“bool”]) --same as line 33

修改table的value

代码如下:

--Altering a table‘s content. Basically manipulating the values of the keys.

lucky= {john=“chips” ,jane =“lemonade”,jolene=“egg salad” }

lucky.jolene = “fruit salad” --changed the value to “fruit salad” instead of “egg salad”

lucky.jerry = “fagaso food” -- adding a new key-value pair to the container lucky.

lucky.john = nil -- remove john from giving anything or from being a key.

table的易变性

代码如下:

a = {}; b = a;

print(a == b) --> true

c,d = {},{};

print(c == d) -->false

table库函数使用

-----------------------------------------------------------

1. table.sort (table [, comp])

Sorts table elements in a given order, in-place, from table[1] to table[n], where n is the length of the table. If comp is given, then it must be a function that receives two table elements, and returns true when the first is less than the second (so that not comp(a[i+1],a[i]) will be true after the sort). If comp is not given, then the standard Lua operator < is used instead.

The sort algorithm is not stable; that is, elements considered equal by the given order may have their relative positions changed by the sort.

代码如下:

name = {“you” ,“me”, “him”,“bill” }

--table.sort - only works with arrays!

table.sort(name)

for k, v in ipairs( name) do

print( k,v)

end

--table.sort uses callbacks. a function that is writtent to be called by a library function.

function cmp( a, b)

if string.sub(a,2 ,2) < string.sub(b,2 ,2) then

return true

else

return false

end

end

table.sort(name, cmp)

for k, v in ipairs( name) do

print( k,v)

end

2. table.insert (table, [pos,] value)

Inserts element value at position pos in table, shifting up other elements to open space, if necessary. The default value for pos is n+1, where n is the length of the table so that a call table.insert(t,x) inserts x at the end of table t.

代码如下:

--table.insert --an easy to copy a table to another table or adding elements to an array.!

foo = {“a” ,“c”, “d”}

bar = {}

function printt( table)

for i=1 ,#table do

print(i,table [i ])

end

end

print(“before insert:” )

printt(foo)

table.insert(foo,2 ,“b”)

print(“after insert” )

printt(foo)

3. table.concat (table [, sep [, i [, j]]])

Given an array where all elements are strings or numbers, returns table[i]..sep..table[i+1] ・・・ sep..table[j]. The default value for sep is the empty string, the default for i is 1, and the default for j is the length of the table. If i is greater than j, returns the empty string.

代码如下:

--table.concat does what it implies. Takes an array and concates to one string.

num = {1 ,2, 3,4,5 ,6}

print(table.concat (num ,“<”))

4. table.remove (table [, pos])

Removes from table the element at position pos, shifting down other elements to close the space, if necessary. Returns the value of the removed element. The default value for pos is n, where n is the length of the table, so that a call table.remove(t) removes the last element of table t.

代码如下:

abc = {“a” ,“b”, “c”}

print(table.remove (abc ,2))

print(“abc length = ” .. #abc)

5. table.maxn (table)

Returns the largest positive numerical index of the given table, or zero if the table has no positive numerical indices. (To do its job this function does a linear traversal of the whole table.)

--table.maxn

代码如下:

apple = {“a” ,“p”,[ 5]=“e”}

print(table.maxn (apple )) -- 5

duck = {[-2 ]=3,[- 1]=0}

print(table.maxn (duck )) -- 0

面向对象编程

代码如下:

--note for a object to work, it needs a closure(inner function with an upvalue(a local value from a higher scope))

--note: the more closures made, the slower the program would run.

function mg1( n)

local function get ()

return n ;

end

local function inc (m )

n = n +m ;

end

return {get = get, inc= inc}

end

bject = mg1(50 )

print(object.get ())

print(object[“get” ]())

object.inc(2 )

print(object.get ())

----------------------------------------

do

local function get (o )

return o.one

end

local function inc (self , two )

self.one = self.one + two

end

function mg3 (one )

return {one = one , get = get , inc = inc }

end

end

a = mg3(50 )

a:get()

a.inc(a,2 )

print(a:get())

----------------------------------------

do

local T = {};

function T:get()

return self.n ;

end

function T:inc(m)

self.n = self.n + m ;

end

function mg4 ( n )

return {n = n , get =T.get , inc =T.inc }

end

end

c = mg4(30 )

print(c:get())

c:inc(4 )

print(c:get())

(完)

篇7:简述Python中的面向对象编程的概念

作者:廖雪峰 字体:[增加 减小] 类型:

这篇文章主要介绍了简述Python中的面向对象编程的概念,面向对象编程是Python的重要特性,需要的朋友可以参考下

面向对象编程――Object Oriented Programming,简称OOP,是一种程序设计思想,OOP把对象作为程序的基本单元,一个对象包含了数据和操作数据的函数。

面向过程的程序设计把计算机程序视为一系列的命令集合,即一组函数的顺序执行。为了简化程序设计,面向过程把函数继续切分为子函数,即把大块函数通过切割成小块函数来降低系统的复杂度。

而面向对象的程序设计把计算机程序视为一组对象的集合,而每个对象都可以接收其他对象发过来的消息,并处理这些消息,计算机程序的执行就是一系列消息在各个对象之间传递。

在Python中,所有数据类型都可以视为对象,当然也可以自定义对象。自定义的对象数据类型就是面向对象中的类(Class)的概念。

我们以一个例子来说明面向过程和面向对象在程序流程上的不同之处。

假设我们要处理学生的成绩表,为了表示一个学生的成绩,面向过程的程序可以用一个dict表示:

std1 = { ‘name‘: ‘Michael‘, ‘score‘: 98 }std2 = { ‘name‘: ‘Bob‘, ‘score‘: 81 }

而处理学生成绩可以通过函数实现,比如打印学生的成绩:

def print_score(std): print ‘%s: %s‘ % (std[‘name‘], std[‘score‘])

如果采用面向对象的程序设计思想,我们首选思考的不是程序的执行流程,而是Student这种数据类型应该被视为一个对象,这个对象拥有name和score这两个属性(Property),

如果要打印一个学生的成绩,首先必须创建出这个学生对应的对象,然后,给对象发一个print_score消息,让对象自己把自己的数据打印出来。

class Student(object): def __init__(self, name, score): self.name = name self.score = score def print_score(self): print ‘%s: %s‘ % (self.name, self.score)

给对象发消息实际上就是调用对象对应的关联函数,我们称之为对象的方法(Method)。面向对象的程序写出来就像这样:

bart = Student(‘Bart Simpson‘, 59)lisa = Student(‘Lisa Simpson‘, 87)bart.print_scorelisa.print_score()

面向对象的设计思想是从自然界中来的,因为在自然界中,类(Class)和实例(Instance)的概念是很自然的。Class是一种抽象概念,比如我们定义的Class――Student,是指学生这个概念,而实例(Instance)则是一个个具体的Student,比如,Bart Simpson和Lisa Simpson是两个具体的Student:

所以,面向对象的设计思想是抽象出Class,根据Class创建Instance。

面向对象的抽象程度又比函数要高,因为一个Class既包含数据,又包含操作数据的方法。

小结

数据封装、继承和多态是面向对象的三大特点,我们后面会详细讲解。

篇8:Perl的面向对象编程(OOP)Unix系统

介绍如何使用Perl的面向对象编程(OOP)特性及如何构建对象,还包括继承、方法重载和数据封装等内容, 一、模块简介 模块(module)就是Perl包(pachage)。Perl中的对象基于对包中数据项的引用。(引用见第x章引用)。 详见 www.nease.net/tppmsgs/msgs0.ht

介绍如何使用Perl的面向对象编程(OOP)特性及如何构建对象,还包括继承、方法重载和数据封装等内容。

一、模块简介

模块(module)就是Perl包(pachage)。Perl中的对象基于对包中数据项的引用。(引用见第x章引用)。

详见clearcase/“ target=”_blank“ >cc”>www.nease.net/tppmsgs/msgs0.htm#28的perlmod和perlobj。

在用其它语言进行面向对象编程时,先声明一个类然后创建该类的对象(实例),特定类所有对象的行为方式是相同的,由类方法确定,可以通过定义新类或从现存类继承来创建类。已熟悉面向对象编程的人可以在此遇到许多熟悉的术语。Perl一直是一个面向对象的语言,在Perl5中,语法略有变动,更规范化了对象的使用。

下面三个定义对理解对象、类和方法在Perl中如何工作至关重要。

.类是一个Perl包,其中含提供对象方法的类。

.方法是一个Perl子程序,类名是其第一个参数。

.对象是对类中数据项的引用。

二、Perl中的类

再强调一下,一个Perl类是仅是一个包而已。当你看到Perl文档中提到“类”时,把它看作“包”就行了。Perl5的语法可以创建类,如果你已熟悉C++,那么大部分语法你已经掌握了。与Perl4不同的概念是用双冒号(::)来标识基本类和继承类(子类)。

面向对象的一个重要特性是继承。Perl中的继承特性与其它面向对象语言不完全一样,它只继承方法,你必须用自己的机制来实现数据的继承。

因为每个类是一个包,所以它有自己的名字空间及自己的符号名关联数组(详见第x章关联数组),每个类因而可以使用自己的独立符号名集。与包的引用结合,可以用单引号(\')操作符来定位类中的变量,类中成员的定位形式如:$class\'$member。在Perl5中,可用双冒号替代单引号来获得引用,如:$class\'$member与$class::$member相同。

三、创建类。

本节介绍创建一个新类的必要步骤。下面使用的例子是创建一个称为Cocoa的简单的类,其功能是输出一个简单的Java应用的源码的必要部分。放心,这个例子不需要你有Java的知识,但也不会使你成为Java专家,其目的是讲述创建类的概念。

首先,创建一个名为Cocoa.pm的包文件(扩展名pm是包的缺省扩展名,意为Perl Module)。一个模块就是一个包,一个包就是一个类。在做其它事之前,先加入“1;”这样一行,当你增加其它行时,记住保留“1;”为最后一行。这是Perl包的必需条件,否则该包就不会被Perl处理。

四、构造函数

构造函数是类的子程序,它返回与类名相关的一个引用,

将类名与引用相结合称为“祝福”一个对象,因为建立该结合的函数名为bless(),其语法为:

bless YeReference [,classname]

YeReference是对被“祝福”的对象的引用,classname是可选项,指定对象获取方法的包名,其缺省值为当前包名。

创建一个构建函数的方法为返回已与该类结合的内部结构的引用。如

sub new {

my $this = {}; # Create an anonymous hash, and #self points to it.

bless $this; # Connect the hash to the package Cocoa.

return $this; # Return the reference to the hash.

}

1;

五、方法

Perl类的方法只不过是一个Perl子程序而已,也即通常所说的成员函数。Perl的方法定义不提供任何特殊语法,但规定方法的第一个参数为对象或其被引用的包。Perl有两种方法:静态方法和虚方法。

静态方法第一个参数为类名,虚方法第一个参数为对象的引用。方法处理第一个参数的方式决定了它是静态的还是虚的。静态方法一般忽略掉第一个参数,因为它们已经知道自己在哪个类了,构造函数即静态方法。虚方法通常首先把第一个参数shift到变量self或this中,然后将该值作普通的引用使用。

六、方法的输出

如果你现在想引用Cocoa.pm包,将会得到编译错误说未找到方法,这是因为Cocoa.pm的方法还没有输出。输出方法需要Exporter模块,在包的开始部分加上下列两行:

require Exporter;

@ISA = qw (Exporter);

Perl类的继承是通过@ISA数组实现的。@ISA数组不需要在任何包中定义,然而,一旦它被定义,Perl就把它看作目录名的特殊数组。它与@INC数组类似,@INC是包含文件的寻找路径。@ISA数组含有类(包)名,当一个方法在当前包中未找到时就到@ISA中的包去寻找。@ISA中还含有当前类继承的基类名。

类中调用的所有方法必须属于同一个类或@ISA数组定义的基类。如果一个方法在@ISA数组中未找到,Perl就到AUTOLOAD()子程序中寻找,这个可选的子程序在当前包中用sub定义。若使用AUTOLOAD子程序,必须用use Autoload;语句调用autoload.pm包。AUTOLOAD子程序尝试从已安装的Perl库中装载调用的方法。如果AUTOLOAD也失败了,Perl再到UNIVERSAL类做最后一次尝试,如果仍失败,Perl就生成关于该无法解析函数的错误。

七、方法的调用

调用一个对象的方法有两种方法,一是通过该象的引用(虚方法),一是直接使用类名(静态方法)。

暂时写到这里,下次继续!

原文转自:www.ltesting.net

篇9:开始尝试面向对象的编程Windows系统

学c++也很久了,不过一直都是些皮毛,现在打算深入下去,所以准备写些有意思的代码,训练自己的思维。 c++的精髓一般很难把握,而且由于它兼容C代码,搞得很多人都用c的思维方式来写c++的代码。 我决定改变这一点。当然要从自身做起。从今天起,我要陆陆续续

学c++也很久了,不过一直都是些皮毛。现在打算深入下去,所以准备写些有意思的代码,训练自己的思维。

c++的精髓一般很难把握,而且由于它兼容C代码,搞得很多人都用c的思维方式来写c++的代码。

我决定改变这一点。当然要从自身做起。从今天起,我要陆陆续续贴些代码上来,争取用面向对象的方式来完成这个项目。

//filename: cell.h

#ifndef _MAC_CELL

#define _MAC_CELL

#include

#include

#include

namespace std {} using namespace std;

const int CELL1=0xa9b0; //┌

const int CELL2=0xa9a4; //─

const int CELL3=0xa9d0; //┬

const int CELL4=0xa9b4; //┐

const int CELL5=0xa9a6; //│

const int CELL6=0xa9c0; //├

const int CELL7=0xa9c8; //┤

const int CELL8=0xa9e0; //┼

const int CELL9=0xa9b8; //└

const int CELL10=0xa9d8;//┴

const int CELL11=0xa9bc;//┘

class pos

{

private:

int x;

int y;

public:

pos();

pos(int lx, int ly);

pos(pos & s);

void perator=(pos s);

int getX();

int getY();

};

class cell

{

private:

pos start;

int width;

int height;

wstring content;

public:

cell();

cell(int x, int y,int w,int h);

cell(pos s,int w,int h);

~cell();

int getWidth();

int getHeight();

wstring getContent();

void setWidth(int w);

void setHeight(int h);

void setContent(wstring s);

};

#endif /* _MAC_CELL */

--------------cut here -----------------------

//filename:cell.cpp

#include

pos::pos():

x(0),y(0)

{

}

pos::pos(int lx,int ly):

x(lx),y(ly)

{

}

pos::pos(pos & s)

{

x=s.getX();

y=s.getY();

}

void pos::operator=(pos s)

{

x=s.getX();

y=s.getY();

}

int pos::getX()

{

return x;

}

int pos::getY()

{

return y;

}

cell::cell():

start(0,0),width(0),height(0),content()

{

}

cell::cell(int x,int y,int w,int h):

start(x,y),width(w),height(h),content()

{

}

cell::cell(pos s,int w,int h):

start(s),width(w),height(h),content()

{

}

int cell::getWidth()

{

return width;

}

int cell::getHeight()

{

return height;

}

wstring cell::getContent()

{

return content;

}

void cell::setWidth(int w)

{

width=w;

}

void cell::setHeight(int h)

{

height=h;

}

void cell::setContent(wstring s)

{

content=s;

}

cell::~cell()

{

}

--------------------cut here--------------------------------

//filename:test.cpp

#include

int main()

{

cell a(0,0,10,10);

a.setContent(L“this is just a test”);

cout << a.getHeight() <

return 0;

}

---------------cut here-----------------------------------------

//compile command:

aCC -AA +DD64 -I/opt/aCC/include_std -I. -lstd_v2 -lCsup_v2 test.cpp cell.cpp -o test

原文转自:www.ltesting.net

【Lua面向对象编程学习笔记】相关文章:

1.Lua table类型学习笔记

2.Flash ActionScript2.0面向对象游戏开发

3.面向对象软件工程开发探讨的论文

4.IOS 开发学习总结 objectivec面向对象之――类和对象(下)

5.面向对象的个人数据中心规划和实施论文

6.党员学习笔记

7.学习笔记范文

8.java学习笔记

9.党员学习笔记标准

10.9月党员学习笔记

下载word文档
《Lua面向对象编程学习笔记.doc》
将本文的Word文档下载到电脑,方便收藏和打印
推荐度: 评级1星 评级2星 评级3星 评级4星 评级5星
点击下载文档

文档为doc格式

  • 返回顶部