加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

lua面向对象是怎么实现的

发布时间:2020-12-14 22:12:09 所属栏目:大数据 来源:网络整理
导读:lua语言中没有真正意义的面向对象,而是通过函数模拟面向对象。我们来看是怎么一步步演化的。 1. 基本的函数 People = {}function People.sayHi() print("Hi,nice to meet you.")endPeople.sayHi();People.sayHi = function() print("Hi,nice to meet you fr

lua语言中没有真正意义的面向对象,而是通过函数模拟面向对象。我们来看是怎么一步步演化的。

1. 基本的函数

People = {}

function People.sayHi()
  print("Hi,nice to meet you.")
end

People.sayHi();

People.sayHi = function()
  print("Hi,nice to meet you from func")
 end
 
People.sayHi();

-- 上面的两种方法效果是一样的
--result:
--Hi,nice to meet you.
--Hi,nice to meet you from func

2. 首先说说怎样遍历table的,(在lua中对象实际就是table,对象.字段名 == table[字段名],所以有必要先讲讲怎么遍历table),用到pairs函数

local arr = {"one","two",["one"] = "xxx",["two"] = "yyy"}

local intValue = 3

for key,val in pairs(arr) do
  print("value of "..key.." is "..val)
end
--输出table所有的属性,包括“数组”属性
--value of 1 is one
--value of 2 is two
--value of one is xxx
--value of two is yyy


for key,val in ipairs(arr) do --友情介绍另外一个函数 ipairs 
  print("value of "..key.." is "..val)
end
--只输出table的“数组”属性
--value of 1 is one
--value of 2 is two

for key,val in pairs(intValue) do
  print("value of "..key.." is "..val)
end

-- 不是table  在调用pairs函数的时候跑出异常
-- bad argument #1 to 'pairs' (table expected,got number)

3. 原来的样子其实没new什么事,长得跟new差好远,不信你看

-- 工具函数
function clone(origin)
  local dest = {}
  for key,value in pairs(origin) do
  	dest[key] = value
  end  
  return dest;	
end

--定义类
People = {}

People.sayHi = function()
  print("Hi,nice to meet you from func")
 end
 

--用类生产对象,对象有了类的方法
p = clone(People) --样子确实差的好多,一点都不优雅   new Peopel()这样写多优雅呀, lua是不是干不了这活儿
p.sayHi();

--result: 结果倒是对了,但是样子太不优雅,我不接受这么难看的写法。。。
--Hi,nice to meet you from func
--Hi,nice to meet you from func

4. 换个模样,我们把clone函数偷偷的封装到一个名字叫new的函数中,修改最后两行代码(从p = clone(People)开始之后的代码替换为下面的样子)(这一步是关键)

function People.new()
   self = clone(People)   
   return self
 end
 

--用类生产对象,对象有了类的方法
--p = clone(People)
--这句话被封装到new函数中

p = People.new()
p.sayHi();

哈哈,是不是可以new对象了。 哎,真是穿个马甲还真是认不出来了。。。(除非看了这篇文章,哈哈,胡扯的,大牛们早就有文章了)


5. 我们想让对象支持 带参数的new(相当于java中带参数的构造函数? 如 new String("parameter")),对People整个‘类’重写,

--定义类
People = {}

People.sayHi = function(self)
  print("Hi,nice to meet you from func,My name is "..self._name) -- 输出_name字段    
  --这一行会报错,attempt to index local 'self' (a nil value)
  --因为下面调用方式是p.sayHi()
 end
 
 
 function People.new(name)
   self = clone(People)   
   
   self._name = name --用构造参数初始化_name字段
   return self
 end
 

--用类生产对象,对象有了类的方法
--p = clone(People)
--这句话被封装到new函数中

p = People.new("stephen")
p.sayHi();


--result:
--attempt to index local 'self' (a nil value)

靠,搞了个参数就报错了,空指针,,没办法我们只能将指针传进去

p.sayHi()? - - -->p.sayHi(p)

- -结果? 改正确了

- -Hi,My name is stephen

哈哈搞定输出来了。

但是

p.sayHi(p)
这个写法也太丑了吧,人家java c++ 程序员会鄙视这么难看的写法的,好,lua帮我们美化一下

p.sayHi(p) - - -> p:sayHi()

- -结果正确

- -Hi,My name is stephen

用冒号(:)代替点号(.),lua会自动帮我们变形,将点号前面的对象传递给参数。

例如? lilei:setGirlFriend("hanmeimei")?? - - ->lilei.setGirlFriend(lilei,"hanmeimei")

弯子转过去了,,在lua中用函数实现了面向对象。


6.等等,继承又怎么实现呢??

哈哈,下面的代码演示一下


-- 工具函数
function clone(origin)
  local dest = {}
  for key,value in pairs(origin) do
  	dest[key] = value
  end  
  return dest;	
end

--定义类
People = {}

People.sayHi = function(self) --父类上的方法
  print("Hi,My name is "..self._name) -- 输出_name字段    
  --这一行会报错,attempt to index local 'self' (a nil value)
  --因为下面调用方式是p.sayHi()
 end
 
People.eat = function()
  print("Different people eat different thing")
end
 
 
People.new = function(name)
   self = clone(People)   
   
   self._name = name --用构造参数初始化_name字段
   return self
 end
 
 
function copy(dest,tab)
  for key,val in pairs(tab) do
  	dest[key] = val
  end

end

-- 定义子类
Chinese = {}

Chinese.new = function(name,hukou)
  self = People.new(name);    --new 父类对象实现继承
  self._hukou = hukou
  
  copy(self,Chinese)  -- 子类上面的 特有的属性也附着到self上面
  
  return self
end

Chinese.eat = function() -- 覆盖父类方法
  print("Eat mantou")
end

Chinese.buyHouse = function()
  print("Can not afford at all")
end

lisi = Chinese.new("lisi","hebei")

print(lisi._name.." is from "..lisi._hukou) -- 父类的成员和自己的成员

lisi:sayHi() -- 继承父类方法
lisi:eat() -- 覆盖父类方法
lisi:buyHouse() -- 子类独有的方法

--result
--lisi is from hebei
--Hi,My name is lisi
--Eat mantou
--Can not afford at all
继承也搞定了,,收工

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读