【热更新知识】学习一 Lua语法学习

1、注释

1.1 单行注释

--注释内容

Lua 复制代码
--单行注释 print打印函数

1.2 多行注释,三种方式

--[[注释内容]]

--[[注释内容]]--

--[[注释内容--]]

Lua 复制代码
--[[
多行
注释
]]

--[[
第二种多行注释
1
2
]]--

--[[
第三种
多行
注释
--]]

2、简单变量

2.1 声明变量,所有的变量申明都不需要申明变量类型它会自动判断类型

Lua 复制代码
a = nil
a = 1
a = 1.2
a = '123'

2.2 nil,有点类似 C#中的null

Lua 复制代码
a = nil
print(a)

2.3 number,所有的数值都是number

Lua 复制代码
a = 1
print(a)
print(type(a))
a = 1.2
print(a)
print(type(a))

2.4 string,字符串的声明 使用单引号或者双引号包裹

Lua 复制代码
a = '123'
b = "456"

2.5 boolean

Lua 复制代码
a = true
print(a)
print(type(a))
a = false
print(a)
print(type(a))

3、string字符串相关介绍

3.1 获取字符串长度

#字符串

Lua 复制代码
s = "aBcdEfg字符串"
s = "字"
--一个汉字占3个长度
--英文字符 占一个长度
print(#s)

3.2 字符串多行打印,lua中也是支持转义字符的

Lua 复制代码
print("123\n123")

s = [[
我是
好人
不要打我
]]
print(s)

3.3 字符串拼接

使用 .. 拼接

Lua 复制代码
--字符串拼接 通过..
print("123".."456")
s1 = "123123"
s2 = 2222
print(s1..s2)

使用方法string.fomat()

Lua 复制代码
print(string.format("我是一个好人,今年%d岁了", 188))
--%d 与数字拼接
--%a 与任何字符拼接
--%s 与字符配对
--.....

3.4 别的类型转字符串,使用方法tostring

Lua 复制代码
a = true
print(tostring(a))

3.5 字符串提供的公共方法

Lua 复制代码
--小写转大写的方法
print(string.upper(str))
print(str)
--大写转小写
print(string.lower(str))
--翻转字符串
print(string.reverse(str))
--字符串索引查找
print(string.find(str, "De"))
--截取字符串
print(string.sub(str, 3, 4))
--字符串重复
print(string.rep(str, 2))
--字符串修改
print(string.gsub(str, "De", "**"))

--字符转 ASCII码
a = string.byte("Llua", 1)
print(a)
a = string.byte("Llua", 2)
print(a)
--ASCII码 转字符
print(string.char(a))

4、运算符

4.1 算数运算符

      • * / % ^
  • 没有自增自减 ++ --
  • 没有复合运算符 += -= /= *= %=
  • 字符串 可以进行 算数运算符操作 会自动转成number
Lua 复制代码
print("加法运算" .. 1 + 2)
a = 1
b = 2
print(1 + 2)
print("123" + 1)
print("123" + "2")

print("减法运算" .. 1 - 2)
print("123.4" - 1)

print("乘法运算" .. 2 * 3)
print("2" * 4)

print("除法运算" .. 4 / 2)
print("1" / 3)

print("取余运算" .. 3 % 2)
print("123.4" % 2)

--^ lua中 该符号 是幂运算符号
print("幂运算" .. 2 ^ 2)
print(2 ^ 4)

4.2 条件运算符

> < >= <= == ~=

Lua 复制代码
-- > < >= <= == ~=
print(3>1)
print(3<1)
print(3>=1)
print(3<=1)
print(3==1)
print(3~=1)
--不等于 是 ~=

4.3 逻辑运算符

C#规则 && || ! "短路"

lua对应中 and or not lua中 也遵循逻辑运算的"短路"规则

Lua 复制代码
--&& || ! "短路"
--and or not lua中 也遵循逻辑运算的"短路"规则
print(true and false)
print(true and true)

print(false or false)
print(true or false)

print(not true)

print(false and print("123"))
print(true or print("456"))

4.4 位运算符,不支持位运算符 需要自己实现

4.5 三目运算符,lua中 也不支持 三目运算

5、条件分支语句

5.1 if 条件 then .....end

Lua 复制代码
--if 条件 then .....end
if a > 5 then
	print("123")
end

if (a > 5) then
	print("lalala")
end

if a >= 3 and a <= 9 then
	print("a在3到9之间")
end

5.2 双分支

Lua 复制代码
--双分支
if a < 5 then
	print("123")
else
	print("321")
end

5.3 多分支

Lua 复制代码
--多分支
if a < 5 then
	print("123")
elseif a == 6 then
	print("6")
elseif a == 7 then
	print("7")
elseif a == 8 then
	print("8")
elseif a == 9 then
	print("9")
else
	print("other")
end

说明

lua中没有switch语法 需要自己实现

lua不支持三目运算符

6、循环语句

6.1 while语句

while 条件 do ...... end

Lua 复制代码
num = 0
--while 条件 do ...... end
while num < 5 do
	print(num)
	num = num + 1
end

6.2 do while语句

repeat ...... until 条件 (注意:条件是结束条件)

Lua 复制代码
num = 0
--repeat ...... until 条件 (注意:条件是结束条件)
repeat
	print(num)
	num = num + 1
until num > 5 --满足条件跳出 结束条件

6.3 for语句

Lua 复制代码
for i = 1, 5 do -- 默认递增 i 会默认+1
	print(i)
end

for i = 1, 10, 2 do --如果要自定义增量 直接逗号后面写
	print(i)
end

for i = 5, 1, -1 do --如果要自定义增量 直接逗号后面写
	print(i)
end

7、函数

7.1 函数声明方式

Lua 复制代码
function 函数名()
	-- body
end

a函数名 = function()
	-- body
end

7.2 无参数无返回值

Lua 复制代码
function F1()
	print("F1函数")
end
F1()

--有点类似 C#中的 委托和事件
F2 = function()
	print("F2函数")
end
F2()

7.3 有参数

Lua 复制代码
function F3(a)
	print("参数:"..tostring(a))
end
F3(1)
F3("123")
F3(true)
--如果传入的参数	和函数参数个数不匹配
--不会报错	只会补空nil 或者 丢弃
F3()
F3(1, 2, 3)

7.4 有返回值

多返回值时 在前面申明多个变量来接取即可

如果变量不够 不影响 只接取对应位置的返回值

如果变量多了 不影响 直接赋值nil

Lua 复制代码
function F4(a)
	return a, "123", true 
end
--多返回值时 在前面申明多个变量来接取即可
--如果变量不够 不影响 只接取对应位置的返回值
--如果变量多了 不影响 直接赋值nil
temp, temp2, temp3, temp4 = F4("123")
print(temp)
print(temp2)
print(temp3)
print(temp4)

7.5 函数的类型

函数类型 就是 function

Lua 复制代码
--函数类型 就是 function
F5 = function()
	print("123")
end
print(type(F5))

7.6 函数的重载

lua中 函数不支持重载,默认调用最后一个声明的函数

Lua 复制代码
--函数名相同 参数类型不同 或者参数个数不同
--lua中 函数不支持重载
--默认调用最后一个声明的函数
function F6()
	print("我是个帅哥")
end

function F6(str)
	print("我怎么样:"..tostring(str))
end

F6()

7.7 变长参数

Lua 复制代码
function F7( ... )
	--变长参数使用 用一个表存起来 再用
	arg = {...}
	for i=1, #arg do
		print(arg[i])
	end
end

F7(1,"123",true,4,5,6)

7.8 函数嵌套

一般闭包情况会使用

Lua 复制代码
function F8()
	return function()
		print("123")
	end
end

F9 = F8()
F9()

--闭包
function F9(x)
	--改变传入参数的生命周期
	return function(y)
		return x + y
	end
end

f10 = F9(10)
print(f10(5))

8、复杂数据类型 table

8.1 数组

8.1.1 数组申明

lua中 索引从1开始

Lua 复制代码
a = {1,2,nil,3,4,5,6,7,"123",true,nil}
--lua中 索引从1开始
print(a[0])
print(a[1])
print(a[8])
print(a[9])
print(a[3])
--#是通用的获取长度的关键字
--在打印长度的时候 空被忽略
--如果表中(数组中)某一位变成nil 会影响#获取的长度
print(#a)
8.1.2 数组的遍历
Lua 复制代码
for i=1,#a do
	print("a["..i.."]:"..tostring(a[i]))
end

8.2 二维数组

8.2.1 二维数组申明
Lua 复制代码
a = {
	{1,2,3,4},
	{5,6,7,8 }
}
print(a[1][3])
print(a[2][2])
8.2.2 二维数组的遍历
Lua 复制代码
for i=1,#a do
	b = a[i]
	for j=1,#b do
		print("a["..i.."]["..j.."]:"..b[j])
	end
end

8.3 自定义索引

Lua 复制代码
aa = {[0] = 1,2,3,4, [-1] = 5,6,7}
print(aa[0])
print(aa[-1])
print(aa[1])
print(aa[2])
print(aa[3])
print(aa[4])
print(aa[5])
print(aa[6])
print(#aa)

8.4 字典

8.4.1 字典的申明
Lua 复制代码
a = {["name"] = "小周", ["age"] = 14, ["1"] = 123}
--访问单个变量 用中括号填键 来访问
print(a["name"])
print(a["age"])
print(a["1"])
--还可以类型 .成员变量 的形式得到值
print(a.name)
print(a.age)
--虽然可以通过 .成员变量的形式得到值 但是不能是数字
print(a["1"])
--修改
a["name"] = "NIBABA"
print(a["name"])
print(a.name)
--新增
a["sex"] = false
str = "name"
print("----------")
print(a[str])
print(a["sex"])
print(a.sex)
--删除
a["sex"] = nil
print(a.sex)
8.4.2 字典的遍历
Lua 复制代码
--如果要模拟字典 遍历一定要用pairs
for k, v in pairs(a) do
	print(k, v, 3)
end

for k in pairs(a) do
	print(k)
	print(a[k])
end

for _,v in pairs(a) do
	print(v)
end

8.5 类和结构体

Lua中是默认没有面向对象的 需要自己实现

Lua中 .和冒号的区别 会默认把调用者 作为第一个参数传入方法中

Lua中类的表现 更像是一个类中有很多 静态变量和函数

Lua 复制代码
--Lua中是默认没有面向对象的 需要自己实现
--成员变量 成员函数。。。
Stundent = {
	--年龄
	age = 1,
	--性别
	sex = false,
	--成长函数
	Up = function()
		--这样写 这个age 和表中的age没有任何关系 它是一个全局变量
		--print(age)
		--想要在表内部函数中 调用表本身的属性或者方法
		--一定要指定是谁的 所有 表名.属性名 或者 表名.方法
		print(Stundent.age)
		print("我成长了")
	end,
	--学习函数
	Learn = function(t)
		print(t.sex)
		print("好好学习,天天向上")
	end
}

Stundent.Learn(Stundent)
--Lua中 .和冒号的区别 会默认把调用者 作为第一个参数传入方法中
Stundent:Learn()

--申明表后 在表外去申明表有的变量和方法
Stundent.name = "小周"

Stundent.Speak = function()
	print("说话")
end
--函数的第三种申明
function Stundent:Speak2()
	--lua中 有一个关键字 self 表示 默认传入的第一个参数
	print(self.name.."说话") 
end

--C#要是使用类 实例化对象new 静态直接点
--Lua中类的表现 更像是一个类中有很多 静态变量和函数
print(Stundent.age)
Stundent.Up()
Stundent.Speak()
Stundent:Speak2()
Stundent.Speak2(Stundent)

8.6 表的公共操作

8.6.1 插入,table.insert()
Lua 复制代码
t1 = {{age = 1, name = "123"}, {age = 2, name = "345"}}

t2 = { name = "DLS", sex = false}

--插入
print(#t1)
table.insert(t1, t2)
print(#t1)
print(t1[1])
print(t1[2])
print(t1[3])
print(t1[3].name)
8.6.2 删除,table.remove()
Lua 复制代码
--删除指定元素
--remove方法 传表进去 会移除最后一个索引的内容
table.remove(t1)
print(#t1)
print(t1[1])
print(t1[2])
print(t1[3])

--remove方法 传两个参数 第一个参数 是要移除内容的表
--第二个参数 是要移除内容的索引
table.remove(t1, 1)
print(#t1)
print(t1[1])
print(t1[2])
print(t1[3])
8.6.3 排序,table.sort()
Lua 复制代码
t2 = {5,2,7,9,5}
--传入要排序的表 默认 降序排序
table.sort(t2)
for _,v in pairs(t2) do
	print(v)
end
8.6.4 降序,table.sort
Lua 复制代码
--传入两个参数 第一个参数是用于排序的表
--第二个参数是 排序规则函数
table.sort( t2,  function(a, b)
	if(a > b) then
		return true
	end
end )
for _,v in pairs(t2) do
	print(v)
end
8.6.5 拼接,table.concat
Lua 复制代码
tb = {"123", "456", "789", "10101"}
str = table.concat( tb, ";" )
print(str)

9、迭代器遍历

迭代器遍历 主要是用来遍历表的

#得到长度 其实并不准确 一般不要用#来遍历表

9.1 ipairs迭代器遍历

Lua 复制代码
--ipairs
--ipairs遍历 还是 从1开始往后遍历的 小于等于0的值得不到
--只能找到连续索引的 键 如果中间断序了 它也无法遍历后面的内容
for i,k in ipairs(a) do
	print("ipairs遍历键值"..i.."_"..k)
end

9.2 ipairs迭代器遍历

Lua 复制代码
--它能够把所有的键都找到 通过键可以得到值
for k,v in pairs(a) do
	print("ipairs遍历键值"..k.."_"..v)
end

for k in pairs(a) do
	print("pairs遍历键"..k)
end

10、多脚本执行

10.1 全局变量和本地变量

Lua 复制代码
--全局变量
a = 1
b = "1dasd"

for i=1,2 do
	c = "TLS"
end

print(c)
--本地(局部)变量的关键字 local
for i=1,2 do
	local d = "TLS"
	print("循环中的d"..d)
end

print(d)

function Fun()
	local tt = "1131"
end
Fun()

print(tt)
local tt2 = "131"
print(tt2)

10.2 多脚本执行

关键字require("脚本名")

Lua 复制代码
--关键字 require("脚本名") require('脚本名')
require("Test")
print(testA)
print(testLocalA)

10.3 脚本卸载

Lua 复制代码
--如果是require加载执行的脚步 加载一次过后不会再被执行
print(package.loaded["Test"])
require("Test")
--package.loaded["脚本名"]
--返回值是boolean 意思是 该脚本是否被执行
print(package.loaded["Test"])
package.loaded["Test"] = nil
print(package.loaded["Test"])

--require 执行一个脚本时 可以在脚本最后返回一个外部希望获取的内容
local testLocalA = require("Test")
print(testLocalA)

10.4 大G表

Lua 复制代码
--_G表是一个总表(table)	它将我们申明的所有全局的变量都存储在其中
for k,v in pairs(_G) do
	print(k, v)
end
--本地变量 加了local的变量是不会存到大_G表中

11、特殊用法

11.1 多变量赋值

Lua 复制代码
a, b, c = 1, 2, 3
print(a)
print(b)
print(c)
--多变量赋值 如果后面的值不够 会自动补空
a, b, c = 1, 2
print(a)
print(b)
print(c) --nil
--多变量赋值 如果后面的值多了 会自动省略
a, b, c = 1, 2, 3,4,5
print(a)
print(b)
print(c)

11.2 多返回值

Lua 复制代码
function Test()
	return 10,20,30,40
end

--多返回值 你用几个变量接 就有几个值
--如果少了 就少接几个 如果多了 就自动补空
a,b,c = Test()
print(a)
print(b)
print(c)

a,b,c,d,e = Test()
print(a)
print(b)
print(c)
print(d)
print(e) --nil

11.3 and or

逻辑与 逻辑或

and or 他们他们不仅可以连接 boolean 任何东西都可以用来连接

在lua中 只有 nil 和 false 才认为是假

"短路" --对于and来说 有假则假 对于or来说 有真则真

所有 他们只需要判断 第一个 是否满足 就会停止计算了

Lua 复制代码
--逻辑与 逻辑或
--and or 他们他们不仅可以连接 boolean 任何东西都可以用来连接
--在lua中 只有 nil 和 false 才认为是假
--"短路" --对于and来说 有假则假 对于or来说 有真则真
--所有 他们只需要判断 第一个 是否满足 就会停止计算了
print( 1 and 2)
print( 0 and 1)
print( nil and 1)
print( false and 1)
print( true and 1)

print(true or 1)
print(false or 1)
print(nil or 2)

lua不支持三目运算符,使用and or 可以实现三目运算

Lua 复制代码
--lua不支持三目运算符 使用and or 可以实现三目运算
x = 3
y = 2
-- ? :
local res = (x>y) and x or y
print(res)

-- (x>y) and x --> x
-- x or y -->x

--  (x>y) and x --> (x>y)
-- (x>y) or y --> y

12、协同程序

12.1 协程的创建

Lua 复制代码
--常用方式
--coroutine.create()
fun = function()
	print(123)
end

--方式1
co = coroutine.create(fun)
--协程的本质是一个线程对象
print(co)
print(type(co))

--方式2
--coroutine.wrap()
co2 = coroutine.wrap(fun)
print(co2)
print(type(co2))

12.2 协程的运行

Lua 复制代码
--第一种方式 对应的 是通过 create创建的协程
coroutine.resume(co)
--第二种方式
co2()

12.3 协程的挂起

Lua 复制代码
fun2 = function()
	local i = 1
	while true do
		print(i)
		i = i + 1
		--协程的挂起函数
		print(coroutine.status(co3))
		print(coroutine.running())
		coroutine.yield(i)
	end
end

co3 = coroutine.create(fun2)
--默认第一个返回值 是 协程是否启动成功
--yield里面的返回值
isOk,tempI = coroutine.resume(co3)
print("tempI"..tempI)
isOk,tempI = coroutine.resume(co3)
print(tempI)
isOk,tempI = coroutine.resume(co3)
print(tempI)

co4 = coroutine.wrap(fun2)
co4()
co4()
co4()

12.4 协程的状态

Lua 复制代码
--coroutine.status(协程对象)
--dead 结束
--suspended 暂停
--running 进行中
print(coroutine.status(co3))
print(coroutine.status(co))

--这个函数可以得到当前正在 运行的协程的线程号
print(coroutine.running())

13、元表

13.1 元表概念

任何表变量都可以作为另一个表变量的元表

任何表变量都可以有自己的元表(爸爸)

当我们子表中进行一些特定操作时

会执行元表中的内容

13.2 设置元表

Lua 复制代码
meta = {}
myTable = {}
--设置元表函数
--第一个参数 子表
--第二个参数 元表(爸爸)
setmetatable(myTable, meta)

13.3 特定操作

13.3.1 __tostring

当子表要被当做字符串使用时 会默认调用它的元表中的tostring方法

Lua 复制代码
meta2 = {
	--当子表要被当做字符串使用时 会默认调用这个元表中的tostring方法
	__tostring = function(t)
		return t.name
	end
}
myTable2 = {
	name = "TLS123"
}
--设置元表函数
--第一个参数 子表
--第二个参数 元表(爸爸)
setmetatable(myTable2, meta2)

print(myTable2)
13.3.2 __call

当子表被当做一个函数来使用时 会默认调用这个__call中的内容

当希望传参数时,默认第一个参数是调用者自己

Lua 复制代码
meta3 = {
	--当子表要被当做字符串使用时 会默认调用这个元表中的tostring方法
	__tostring = function(t)
		return t.name
	end,
	--当子表被当做一个函数来使用时 会默认调用这个__call中的内容
	--当希望传参数是 一定要记住 默认第一个参数 是调用者自己
	__call = function(self, a)
		print(self)
		print(a)
		print("TLS好帅")
	end
}
myTable3 = {
	name = "TLS123"
}
--设置元表函数
--第一个参数 子表
--第二个参数 元表(爸爸)
setmetatable(myTable3, meta3)
--把子表当做函数使用 就会调用元表的 __call
myTable3(1)
13.3.3 运算符重载

|----------|----------|
| 运算符+ | __add |
| 运算符- | __sub |
| 运算符* | __mul |
| 运算符/ | __div |
| 运算符% | __mod |
| 运算符^幂运算 | __pow |
| 运算符== | __eq |
| 运算符< | __lt |
| 运算符<= | __le |
| 运算符.. | __concat |

Lua 复制代码
meta4 = {
	--相当于运算符重载 当子表使用+运算符时 会调用该方法
	--运算符+
	__add = function(t1, t2)
		return t1.age + t2.age
	end,
	--运算符-
	__sub = function(t1, t2)
		return t1.age - t2.age
	end,
	--运算符*
	__mul = function(t1, t2)
		return t1.age * t2.age
	end,
	--运算符/
	__div = function(t1, t2)
		return t1.age / t2.age
	end,
	--运算符%
	__mod = function(t1, t2)
		return t1.age % t2.age
	end,
	--运算符^ 幂运算
	__pow = function(t1, t2)
		return t1.age ^ t2.age
	end,
	--运算符==
	__eq = function(t1, t2)
		return t1.age == t2.age
	end,
	--运算符<
	__lt = function(t1, t2)
		return t1.age < t2.age
	end,
	--运算符<=
	__le = function(t1, t2)
		return t1.age <= t2.age
	end,
	--运算符..
	__concat = function(t1, t2)
		return t1.age .. t2.age
	end
}
myTable4 = {
	age = 1
}

setmetatable(myTable4, meta4)
myTable5 = {
	age = 2
}
setmetatable(myTable5, meta4)

print(myTable4 + myTable5)
print(myTable4 - myTable5)
print(myTable4 * myTable5)
print(myTable4 / myTable5)
print(myTable4 % myTable5)
print(myTable4 ^ myTable5)

print(myTable4 == myTable5)
print(myTable4 < myTable5)
print(myTable4 <= myTable5)
print(myTable4 > myTable5)
print(myTable4 >= myTable5)
print(myTable4 .. myTable5)
13.3.4 __index

当子表中 找不到某一个属性时

会到元表中 __index指定的表去索引

Lua 复制代码
meta6 = {
	age = 1
}
meta6.__index = meta6
myTable6 = {}
setmetatable(myTable6, meta6)

--得到元表的方法
print(getmetatable(myTable6))

--__index 当子表中 找不到某一个属性时
--会到元表中 __index指定的表去索引
print(myTable6.age)
--rawget 当我面使用它时 会去找自己身上有没有这个变量
--myTable6.age = 4
print("rawget")
print(rawget(myTable6, "age"))
13.3.5 __newindex

__newIndex 当子表赋值时,如果赋值一个不存在的索引

如果元表设置了__newIndex,那么会把这个值赋值到元表的__newindex所指的表中 不会修改自己

Lua 复制代码
--newIndex 当赋值时 如果赋值一个不存在的索引
--那么会把这个值赋值到newindex所指的表中 不会修改自己
meta7 = {}
meta7.__newindex = {
	age = 1
}
myTable7 = {}
--myTable7.__newindex = {}
setmetatable(myTable7, meta7)
myTable7.age = 14
print(myTable7.age)
print(meta7.__newindex.age)
rawset(myTable7, "age", 123)
print(myTable7.age)

14、面向对象

14.1 封装

Lua 复制代码
--面向对象 类 其实都是基于 table来实现
--元表相关的知识
Object = {}
Object.id = 1

function Object:Test()
	print("TestFun id: "..self.id)
end

--冒号 是会自动将调用这个函数的对象 作为第一个参数传入的写法
function Object:new()
	--self 代表的是 默认传入的第一个参数

	--对象就是变量 返回一个新的变量
	--返回出去的内容 本质上就是表对象
	local obj = {}
	--元表知识 __index 当找自己的变量 找不到时 就会去找元表当中__index指向的内容
	self.__index = self
	setmetatable(obj, self)
	return obj
end

local myObj = Object:new()
print(myObj)
print(myObj.id)
myObj:Test()

myObj.id = 2
--对空表中 申明一个新的属性 叫做id
print(myObj.id)
print(Object.id)
myObj:Test()

14.2 继承

Lua 复制代码
--C# class 类名 : 继承类
--写一个用于继承的方法
function Object:subClass(className)
	-- _G知识点 是总表 所有申明的全局变量 都以键值对的形式存在其中
	_G[className] = {}
	--写相关继承的规则
	--用到元表
	local obj = _G[className]
	self.__index = self
	--子类 定义一个base属性 base属性代表父类
	obj.base = self
	setmetatable(obj, self)
	return obj
end

Object:subClass("Person")

local p1 = Person:new()
print(p1.id)
p1.id = 100
print(p1.id)
p1:Test()

Object:subClass("Monster")
local m1 = Monster:new()
print(m1.id)
m1.id = 10
print(m1.id)
m1:Test()

14.3 多态

Lua 复制代码
--相同行为 不同表现 就是多态
--相同方法 不同执行逻辑 就是多态
Object:subClass("GameObject")
GameObject.posX = 0
GameObject.posY = 0
function GameObject:Move()
	self.posX = self.posX + 1
	self.posY = self.posY + 1
	print("移动后位置pos:("..self.posX..","..self.posY..")")
end

GameObject:subClass("Player")
function Player:Move()
	--base 指的是 GameObject 表(类)
	--这种方式调用 相对与时把基类 作为第一个参数传入了方法中
	--避免把基类表 传入到方法中 这样相当于就是公用一张表的属性了
	--我们如果要执行父类逻辑 不要直接使用冒号调用
	--要通过.调用 然后自己传入第一个参数
	self.base.Move(self)
end

local p1 = Player:new()
p1:Move()
p1:Move()
--目前这种写法 有坑 不同对象使用的成员变量 居然是相同的成员变量
local p2 = Player:new()
p2:Move()

15、基类 Object

15.1 实现万物之父 所有对象的基类 Object

Lua 复制代码
--面向对象实现
--万物之父 所有对象的基类 Object

Object = {}
function Object:new()
	local obj = {}
	--给空对象设置元表 以及 __index
	self.__index = self
	setmetatable(obj, self)
	return obj
end
function Object:subClass(className)
	--根据名字生成一张表 就是一个类
	_G[className] = {}
	local obj = _G[className]
	--设置自己的"父类"
	obj.base = self
	--给子类设置元表 以及 __index
	self.__index = self
	setmetatable(obj, self)
	--return obj
end

15.2 使用方法

Lua 复制代码
--申明一个新的类
Object:subClass("GameObject")
--成员变量
GameObject.posX = 0
GameObject.posY = 0
--成员方法
function GameObject:Move()
	self.posX = self.posX + 1
	self.posY = self.posY + 1
end

--实例化对象使用
local obj = GameObject:new()
print(obj.posX)
obj:Move()
print(obj.posX)
相关推荐
心前阳光36 分钟前
Unity-通过Transform类学习迭代器模式
学习·unity·迭代器模式
SlowFeather3 小时前
Apache 反向代理Unity服务器
服务器·unity·apache
惊鸿醉4 小时前
⭐ Unity 实现屏幕涟漪效果:自动生成 \ 点击交互生成涟漪
unity·游戏引擎
WarPigs15 小时前
Unity网络通信笔记
网络·unity
aerror18 小时前
如何正确的用Trae 打开 Unity 3D 项目
3d·unity·游戏引擎
步、步、为营20 小时前
.NET 的IOC框架Unity代码示例
unity·游戏引擎·.net
留待舞人归1 天前
【Unity优化】提高热更新和打包速度
游戏·unity·游戏引擎·unity3d·优化
tealcwu1 天前
【Unity踩坑】Unity 6在Mac平台编译运行时去除‘trial version‘
macos·unity·游戏引擎
为你写首诗ge1 天前
【热更新知识】学习三 XLua学习
unity·lua