lua实现面向对象的特性

开发 前端
lua本身不支持面向对象的特性,但是由于lua是基于原型(prototype)的语言,要实现面向对象的特性也是有一定的方法的,实现方式有很多种, 总结了一下我最近对使用lua实现面向对象的特性

lua本身不支持面向对象的特性,但是由于lua是基于原型(prototype)的语言,要实现面向对象的特性也是有一定的方法的,实现方式有很多种, 总结了一下我最近对使用lua实现面向对象的特性,主要可以分为以下两种不同的方式来实现:

1、使用metatable的__index域实现,实现的时候需要利用的lua语言的一些特性才可以实现,主要有:

a、将table b作为table a的一个prototype的方法:setmetatable(a, {__index = b});

b、lua5.1中实现的module机制;

通过这两个技术你可以实现一个基础类,实现类的inherit和new方法:

  1. --filename:"obj.lua" 
  2. local setmetatablesetmetatable = setmetatable 
  3. module"obj" function inherit (self) 
  4. return function (newclass) 
  5. setmetatable (newclass, self) 
  6. selfself.__index = self   
  7. return newclass   end   
  8. end   
  9. function new (self, o)   
  10. oo = o or {}   
  11. setmetatable (o, self)   
  12. selfself.__index = self   
  13. return o   end   
  14. ----------------------------------------------------------------------   
  15. --Now you can define a new class which extends the previous `obj':   
  16. --filename:"myobj.lua"   
  17. local obj = require"obj"   
  18. module ("myobj", obj:inherit())   
  19. --Class `myobj' will "inherit" the methods `new' and `inherit' from class `obj'. 

优点:

1、由于子类的很多数据和方法都是共用了父类的,用到父类的数据和方法的时候,只是在使用的时候才直接调用父类的方法和数据,这样可以减少程序内存的消耗,更主要的是,父类在运行期的修改是会影响到子类的;

2、充分利用了lua语言的特性,父类的方法和数据的访问是解析器来做的,所以效率上的开销还是比较小的;

缺点:

1、如果父类中有一个数据是一个引用的时候(如table)的时候,就会出现在一个子类中操作这个table会改变其他子类的情况,造数据的不 一致,所以应该尽量避免这种类的创建,如果有这样的需求的话,就需要对inherit和new函数进行一些特殊的操作,简单来说就是加一个init函数, 将所有这类的数据都显示的创建一下。

2、由于每次取操作都需要在metatable中取,所以,每次就会增加一层继承,就增加一个函数调用的开销,虽然是由解析器来做的,但是如果层次多了的话,还是有开销的;

3、使用table拷贝的方式实现,实现的时候利用的lua的技术为:

a、使用lua实现一个table拷贝的函数;

b、lua5.1中实现的module机制;

通过这两个技术你可以实现一个基础类,实现类的inherit和new方法:

  1. ----------------------------------------------------------------------- 
  2.   --filename:"obj.lua" 
  3.   local setmetatablesetmetatable = setmetatable 
  4.   module"obj" 
  5.   function inherit (self) 
  6.   return function (newclass) 
  7.   newclass = table.clone(self) 
  8.   return newclass 
  9.   end 
  10.   end 
  11.   function new (self, o) 
  12.   oo = o or {} 
  13.   o = table.clone(self) 
  14.   return o 
  15.   end 
  16.   ---------------------------------------------------------------------- 
  17.   --Now you can define a new class which extends the previous `obj': 
  18.  
  19.   --filename:"myobj.lua" 
  20.   local obj = require"obj" 
  21.   module ("myobj", obj:inherit()) 
  22.   --Class `myobj' will "inherit" the methods `new' and `inherit' from class `obj'. 

优点:

1、父类中的数据是全部拷贝到子类中的,所以,不存在数据不一致的情况;

2、所有的函数调用和数据调用都是直接调用每个实例的,不需要到父类中查找;

缺点:

1、全部数据的copy,在创建的时候就会增加一个table copy的过程,影响效率;

2、全部数据和方法都是在创建的时候拷贝一份的,会增加很多的内存消耗,而且如果在运行期改变了父类,并不能改变子类;

总结:

结合这两种方式的有缺点,从一个面向对象的角度来说,第一种方式更加适合实现面向对象的特性,第二种方式对面向对象的模拟就牵强一些(缺点 2),但是从使用的角度来说,因为在访问数据和方法速度上,第二种方式还是有优势的,所以,在具体的使用的时候,可以灵活一下使用,将两者结合一下。

比如说,对于客户端这边来说,类在开始创建好了以后就一般不需要修改了,而且子类一般都是需要父类的所有的方法和数据的,所有我们就可以使用第 二种方式,而生成对象实例的时候,对象的实例一般都不会调用类的所有的方法,而且用完了这个实例,就会销毁的,所以,我们这里就可以采用第一种方式,结合 一下设计可以是:

  1. ----------------------------------------------------------------------- 
  2.   --filename:"obj.lua" 
  3.   local setmetatablesetmetatable = setmetatable 
  4.   module"obj" 
  5.   function inherit (self) 
  6.   return function (newclass) 
  7.   newclass = table.clone(self) 
  8.   return newclass 
  9.   end 
  10.   end 
  11.   function new (self, o) 
  12.   oo = o or {} 
  13.   setmetatable (o, self) 
  14.   selfself.__index = self 
  15.   return o 
  16.   end 
  17.   ---------------------------------------------------------------------- 
  18.   --Now you can define a new class which extends the previous `obj': 
  19.  
  20.   --filename:"myobj.lua" 
  21.   local obj = require"obj" 
  22.   module ("myobj", obj:inherit()) 
  23.   --Class `myobj' will "inherit" the methods `new' and `inherit' from class `obj'. 

这里的关键是继承是copy出来的,而实例是采用metatable的方式实现的。

原文链接:http://tech.it168.com/j/2008-02-17/200802171004466.shtml

责任编辑:陈四芳 来源: it168.com
相关推荐

2012-03-13 16:39:52

Java

2009-10-13 14:19:03

VB.NET面向对象编

2009-05-21 09:08:52

接口C++面向对象

2022-10-21 09:01:41

StudentC++类型

2023-01-10 09:38:09

面向对象系统

2022-08-16 07:57:30

架构

2011-08-24 09:54:05

Lua字符春交互

2009-12-22 01:54:50

C++之父Bjarne Stro

2023-04-19 08:43:52

Python面向对象编程

2020-04-15 11:07:31

C语言对象思想

2021-10-21 18:47:37

JavaScript面向对象

2013-03-11 09:23:22

Go语言面向对象

2010-07-13 14:54:15

Perl面向对象编程

2010-07-13 10:47:18

Perl面向对象

2009-07-14 16:51:50

Jython中的对象

2009-01-04 09:08:30

面向对象继承接口

2022-10-12 08:38:51

C语言classC++

2021-05-20 08:54:16

Go面向对象

2022-07-30 23:41:53

面向过程面向对象面向协议编程

2024-04-02 07:32:58

Go语言接口
点赞
收藏

51CTO技术栈公众号