语雀内容

封装

—— 面向对象
_print(“####====封装====####”)
—— 封装
_— 面向对象,类 都是基于table实现
—[[
— 类似于静态类
Object = {}
Object.id = 1
— 冒号 自动将调用函数的对象作为第一个参入传入(self)
function Object:new()
— 对象即为变量,返回一个新的变量
— 返回出去的内容 本质上是一个新的表对象
local obj = {}
return obj
end
local myObj = Object:new()
print(myObj) —> table: 0000000000a198a0
print(myObj.id) —> nil
]]

— 类似于静态类
Object = {}
Object.id = 1
— 冒号 自动将调用函数的对象作为第一个参入传入(self)
function Object:new()
— 对象即为变量,返回一个新的变量
— 返回出去的内容 本质上是一个新的表对象
local obj = {}
—元表知识 index当找子表变量无法找到,去元表中找index指向的内容
setmetatable(obj, self)
self._index = self
return obj
end
local myObj = _Object
:new()
print(myObj) —> table: 00000000007a97e0
print(myObj.id) —> 1
function Object:test()
print(self.id)
end
myObj:test() —> 1
myObj.id = 2
— 对空表中声明一个新的属性 id
print(Object.id) —> 1
myObj:test() —> 2

继承

print(“####====继承====####”)
—— 继承
—[[
function Object:subClass(className)
G 总表 所有声明的全局变量 都以键值对的形式存在其中
_G[className] = {} — 构建出这张表
end
Object:subClass(“Person”)
print(Person) —> table: 0000000000849860
]]
function _Object
:subClass(className)
G 总表 所有声明的全局变量 都以键值对的形式存在其中
_G[className] = {} — 构建出这张表
— 继承Object
local obj = _G[className]
self.__index = self
setmetatable(obj, self)
end
_Object
:subClass(“Person”)
print(Person.id) —> 1
local p1 = Person:new()
p1:test() —> 1
Object:subClass(“Monster”)
local m1 = Monster:new()
m1:test() —>1
m1.id = 100
p1:test() —> 1
m1:test() —> 100
image.png

多态

print(“####====多态====####”)
—— 多态
— 相同行为 不同表现
— 相同方法 不同执行逻辑
Object:subClass(“GameObject”)
GameObject.posX = 0
GameObject.posY = 0
function GameObject:move()
self.posX = self.posX + 1
self.posY = self.posY + 2
print(self.posX, self.posY)
end
GameObject:subClass(“Player”)
local p1 = Player:new()
p1:move() —> 1 2
function Player:move()
self.posX = self.posX + 3
self.posY = self.posY + 4
print(self.posX, self.posY)
end
local p2 = Player:new()
p2:move() —> 3 4
print(“####==保留父类行为方法==####”)
— 如何保留父类的行为逻辑(行为方法)?
function Object:subClass(className)
G 总表 所有声明的全局变量 都以键值对的形式存在其中
_G[className] = {} — 构建出这张表
— 继承Object
local obj = _G[className]
— 子类 定义一个base属性 base属性代表父类
obj.base = self
self.__index = self
setmetatable(obj, self)
end
_Object
:subClass(“GameObject”)
GameObject.posX = 0
GameObject.posY = 0
function GameObject:move()
self.posX = self.posX + 1
self.posY = self.posY + 2
print(self.posX, self.posY)
end
GameObject:subClass(“Player”)
function Player:move()
self.posX = self.posX + 3
self.posY = self.posY + 4
print(self.posX, self.posY)
end
function Player:baseMove()
self.base:move()
end
local p1 = Player:new()
p1:move() —> 3 4
p1:baseMove() —> 1 2
local p2 = Player:new()
p2:baseMove() —> 2 4

— 重要
— p1与p2共用self.posX,self.posY(相同的成员变量),违背了面向对象的特点
— 分析:
function Player:baseMove()
— base 为 GameObject类
— 将GameObject基类 作为第一个参数传入进行调用
— 避免 基类表传入方法中 相当于共用了一张表的属性
—self.base:move() — 等于传入了self.base
— 避免使用冒号调用,自行传入第一个参数!!!
self.base.move(self)
end
print(“#### #### ####”)
— 将两个对象的属性分开了,分别具有自己的属性
local p1 = Player:new()
p1:baseMove() —> 3 6
local p2 = Player:new()
p2:baseMove() —> 3 6
语雀内容