Lua中的面向对象

一.元表的概念

Lua模拟类和对象,理解主表/元表关系是关键,有表A和表B,A是主表,B是元表(子表),那么我们可以通过主表访问元表中的元素。实现代码如下:

--[[
tableA = {} --表A [主表]
tableB = {} --表B [元表/子表]

setmetatable(tableA, tableB) -- tableB就是tableA的元表.

print(getmetatable(tableA)) -- 判断tableA是否有元表

--]]


tableA = {name = "lsw", age = 100}
tableB = {gender = "男", address = "湖北武汉"}

setmetatable(tableA, tableB)
tableB.__index = tableB -- 设置元表的__index索引.

print(tableA.name, tableA.age)
--print(tableA["name"])
print(tableA.gender, tableA.address)
  1. 表 A 内有自己键值对元素,表 B 内也有自己的键值对元素,同时表 B 还是 表 A 的元表,两个表建立了“从属关系”,一般我们都是直接访问表 A。
  2. 我们可以直接通过“表名.键名”的方式访问表 A 中的成员,但是元表内的 成员,我们是访问不到的,会返回 nil。
  3. 如何通过“表名.键名”直接访问到元表中的成员哪??? 我们需要设置元表的“__index 索引”,让这个索引指向元表自身,代码如下: 元表名.__index = 元表名
  4. 设置完毕__index 索引后,我们再使用“表名.键名”的方式访问成员,如 果表 A 中没有,就会自动访问表 B 中的成员。

二.Lua模拟类

--初始化了一个类.
Person = {name, age, gender, address = "中国"} --在Person类中模拟字段.

--模拟构造方法.
function Person:New()
	obj = {} --初始化一个新的表.
	setmetatable(obj, Person) --把当前的类[表]设置为新表的元表.
	Person.__index = Person --指定元表的__index索引.
	return obj
end


--模拟一个方法.
function Person:Show()
	print(self.name, self.age, self.gender, self.address)
end

--实例化对象.
lkk = Person:New()
lkk.name = "lsw"
lkk.age = 110
lkk.gender = "男"
lkk.address = "湖北武汉"
lkk:Show()

mk = Person:New()
mk.name = "Monkey"
mk.age = 10
mk.gender = "男"
mk:Show()

print(lkk == mk)

三.进一步完善

--创建一个Hero类.
Hero = {name, hp, mp, attack} --定义相关字段.

--定义构造方法.
function Hero:New(name, hp, mp, attack)
	local obj = {}
	--setmetatable(obj, Hero)
	--Hero.__index = Hero
	setmetatable(obj, self)
	self.__index = self
	self.name = name
	self.hp = hp
	self.mp = mp
	self.attack = attack
	return obj
end

--定义相关方法.
function Hero:Attack1()
	print(self.name .. "攻击方法一执行啦..")
end

function Hero:Attack2()
	print(self.name .. "攻击方法二执行啦..")
end

function Hero:ToString()
	print(string.format("角色名:%s,生命值:%s,法力值:%s,攻击力:%s", self.name, self.hp, self.mp, self.attack))
end


--实例化对象.
--mk = Hero:New()
--mk.name = "mkcode"
--mk.hp = 1000
--mk.mp = 500
--mk.attack = 100

mk = Hero:New("Monkey", 9999, 8888, 7777)
mk.hp = 1000000
mk:Attack1()
mk:Attack2()
mk:ToString()

--在 Lua 语言的构造方法中,我们可以做两件事情: 
--①必须要完成一个新的“对象的实例化”,也就是初始化一个新的表; 
--②同时还可以完成对象字段的初始化,这一步是可选操作。
  1. 在构造方法中指定__index 索引的时候可以用 self 代表当前“类”;
  2. 在构造方法中使用 self 表示当前类中的成员。 

四.继承关系模拟


--创建一个动物类.
Animal = {name} --字段.

--构造方法.
function Animal:New(name)
	local obj = {}
	setmetatable(obj, self)
	self.__index = self
	self.name = name
	return obj
end

--普通方法.
function Animal:ToString()
	print(self.name .. "Animal类中的方法")
end

--子类继承父类.
Cat = Animal:New(nil)

--子类的构造方法.
function Cat:New(name)
	local obj = Animal:New(name)
	setmetatable(obj, self)
	self.__index = self
	--self.name = name
	return obj
end

--子类当的普通方法.
function Cat:Eat(food)
	print(self.name .. "吃:" .. food)
end


--[[
--创建对象.
jfm = Animal:New("加菲猫")
jfm:ToString()
print(jfm.name)
--]]

--通过子类实例化对象.
jfm = Cat:New("加菲猫")
jfm:ToString()
jfm:Eat("鱼")
print(jfm.name)

tom = Cat:New("汤姆")
tom:ToString()
tom:Eat("杰瑞")
print(tom.name)

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值