lua面向对象是怎么实现的

转载自:http://blog.csdn.net/s_xing/article/details/19575059

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

  1. 基本的函数

[plain] view plain copy

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

[html] view plain copy

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)  
  1. 原来的样子其实没new什么事,长得跟new差好远,不信你看

[html] view plain copy

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

[html] view plain copy

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


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

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

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

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

[html] view plain copy

--定义类  
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)

  • -结果 改正确了

    扫描二维码关注公众号,回复: 4220132 查看本文章
  • -Hi, nice to meet you from func, My name is stephen

哈哈搞定输出来了。

但是

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

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

  • -结果正确

  • -Hi, nice to meet you from func, My name is stephen

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

例如 lilei:setGirlFriend(“hanmeimei”) - - ->lilei.setGirlFriend(lilei, “hanmeimei”)

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

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

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

[html] view plain copy

-- 工具函数  
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, nice to meet you from func, 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, nice to meet you from func, My name is lisi  
--Eat mantou  
--Can not afford at all  

继承也搞定了,,收工

猜你喜欢

转载自blog.csdn.net/NippyLi/article/details/79573431