lua的面向对象实现
百度搜索一下,给出出的解决方案和学习帖子很多,可是我还是有很多的问题!
(1)什么是面向对象?
(2)lua中怎么实现面向对象?
(3)什么样的实现既简单又能完成我的功能?
(4)一定要按照c++的方式实现类的继承吗?
能力有限,在学习lua面向对象的时候我比较喜欢两种实现方式:
1. 简单粗暴的实现
参考[1]:参考同事的方法,如果借鉴、转载请注明
在lua中,我们知道table是万能的一个类型,当我们用table实现一个基类和子类的时候,他们都是确确实实存在的一个个table,都是有地址的。不会说像c++一样,类定义是类定义,只有new出来才是真正可以使用的,而lua却不是这样。所以,最简单的一种方法就是,每次继承基类的时候,直接copy基类的所有内容,函数除外,其他的成员都重新复制一遍,如果是table的话重新构建一个,并且把内容拷贝过来。代码如下:
--lua面向对象:简单粗暴的实现
function copytable(tbArg)
local tbCollsion = {} --local的作用域问题
local copy
copy = function (obj)
if type(obj) ~= "table" then
return obj;
end
--检查是否有嵌套循环的table
if tbCollsion[obj] then
return tbCollsion[obj];
end local tbNew = {}
tbCollsion[obj] = tbNew;
--递归复制
for k, v in pairs(obj) do
tbNew[k] = copy(v);
end
--复制完之后,元表关系也要保留下来
return setmetatable(tbNew, getmetatable(obj))
end return copy(tbArg);
end function inherit(tbBase, tbClass)
--复制基类
local tbNew = copytable(tbBase) local tm = {}
tm.__index = tbClass;
setmetatable(tbNew, tm) --修改tbBase为tbClass中的成员或者新增加tbClass中的成员
if tbClass then
for k, v in pairs(tbClass) do
tbNew[k] = v
end
end return tbNew;
end
--使用
local tbObject = {}
local tbFruit = inherit(tbObject)
local tbApple = inherit(tbFruit)
local tbBanana = inherit(tbFruit)
local tbBanana1 = inherit(tbFruit)
local tbBanana2 = inherit(tbFruit, tbBanana1)
优点:
(1)好理解
(2)好用,不会出现共用一个table引用,导致其中一个修改影响了另外一个
(3)共享函数引用
缺点:
(1)真正意义上的面向对象,继承等概念不清晰
(2)一个子类new多个对象的概念是没有的,和继承已经混在了一起,所以如果要实现new多个对象的话,有代码冗余
2. 概念意义上的实现
参考[2]:云风的blog,如果借鉴、转载请注明
这种从概念上实现面向对象的方法做到以下几点:
(1)有类定义和对象的概念,类定义通过new来创建对象,并且同时调用自己的构造函数
(2)子类可以访问基类的成员函数
(3)类定义不能够调用函数(除了new之外),只有对象才能调用函数
(4)构造函数调用有和c++一样的层级关系,先调用父类的构造函数,再调用子类的构造函数
--lua面向对象:概念意义上的实现
local _class={} function class(super)
local class_type={}
--注意:因为重载了__newindex函数, 所以ctor不要定义为nil
class_type.ctor=false
class_type.super=super
class_type.new=function(...)
local obj={}
--下面的块只做了一件事:依次从父类到当前子类调用构造函数ctor
do
local create
create = function(c,...)
if c.super then
create(c.super,...)
end
if c.ctor then
c.ctor(obj,...)
end
end create(class_type,...)
end
setmetatable(obj,{ __index=_class[class_type] })
return obj
end --新加成员:防止定义类调用函数
local vtbl={}
_class[class_type]=vtbl setmetatable(class_type,{__newindex=
function(t,k,v)
vtbl[k]=v
end
}) --只有定义类修改了__newindex
--vbtl只属于定义类
--new出来的对象共享所有定义类的引用,但独享自己新增加的成员变量
if super then
setmetatable(vtbl,{__index=
function(t,k)
local ret=_class[super][k]
vtbl[k]=ret
return ret
end
})
end return class_type
end
说明几点:
(1)只有定义类修改了__newindex
(2)vbtl只属于定义类
(3)new出来的对象共享所有定义类的引用,但独享自己新增加的成员变量
有点:
(1)概念上更加清晰,熟悉c++面向对象的很容易了解这个继承的关系
(2)写法上感觉很牛逼,做到了定义不能调用函数这一点
(3)共享函数引用
缺点:
(1)概念上清晰的成本是要更多的时间去理解
(2)虽然做到了c++类定义和对象上的概念区别,但是还是有多东西没有实现
(3)对象也可以定义自己的函数,这一点就直接打破了区分定义和对象的本源,但是价值还是有的
(4)所有new出来对象共享类定义的引用对象,包括不需要复用的函数和table。由此多个对象共享一个定义的table很是个问题!
* 针对(4),可以通过实现定义的init函数,在init函数给不同的对象初始化不同的数据,即使是table!
参考:
[1]同事
[2]http://blog.codingnow.com/cloud/LuaOO
lua的面向对象实现的更多相关文章
- Lua 之面向对象编程
Lua 之面向对象编程 Lua并不是为面向对象而设计的一种语言,因此,仅从原生态语法上并不直接支持面向对象编程,但Lua的设计中仍然包含了很多面向对象的思想,理解它们也更有助于理解Lua自身的一些高级 ...
- Lua学习----面向对象编程
1.类 再Lua中可以使用表和函数实现面向对象,将函数和相关的数据放置放置于同一个表中就形成了对象.例如: Measure = {width = 0, height = 0} function Mea ...
- Lua的面向对象,封装,继承,多态
概述 我们总所周知对象是由属性和方法组成的,要用lua要描述一个对象,也必然要有这两个特性,属性和方法.lua的基本结构是table,所以Lua的类,其实都是table,因为它可以存储普通的变量又可以 ...
- lua table面向对象扩展
一 .table扩展 -- 返回table大小 table.size = function(t) local count = 0 for _ in pairs(t) do count = count ...
- LUA之面向对象
Account = { balance=0, withdraw = function (self, v) self.balance = self.balance - v end } function ...
- lua的面向对象
Lua中的table就是一种对象,但是如果直接使用仍然会存在大量的问题,见如下代码: Account = {balance = } function Account.withdraw(v) Accou ...
- Lua中面向对象
一.Lua中类的简单实现: (1)版本——摘自 Cocos2.0中的: --Create an class. function class(classname, super) local superT ...
- 【Lua】面向对象编程(二)
多重继承: module(...,package.seeall) local function search(k,plist) ,#plist do local v=plist[i][k] if ...
- 【Lua】面向对象编程(一)
类和对象: account.lua module(...,package.seeall) Account={balance=} Account.new=function(self,o) local ...
随机推荐
- 【OpenCV-Python】-图像平滑
原文为段立辉翻译,感谢Linux公社www.linuxidc.com此文档为自学转述,如有侵权请联系本人. 目标: • 学习使用不同的低通滤波器对图像进行模糊 • 使用自定义的滤波器对图像进行卷积(2 ...
- Oracle系统表整理 --sql
-- DBA/ALL/USER/V_$/GV_$/SESSION/INDEX开头的绝大部分都是视图-- DBA_TABLES意为DBA拥有的或可以访问的所有的关系表.-- ALL_TABLES意为某一 ...
- C# 实现IP视频监控(摄像头)画面推送(简单的不能再简单的DEMO)
最近继续在家休息,在完成上一个Python抓取某音乐网站爬虫后,琢磨着实现一个基于HTTP推送的 IP视频监控,比如外出的时候,在家里 开启一个监控端(摄像头+服务端),可以看到实时画面,如果再加上自 ...
- selenium+Python(Page Object 设计模式实例)
以下实例演示了采用了page Object设计模式的方式登录qq空间: 1.创建基础类page:在初始方法__init__()定义驱动的(driver),基本url(base_url)和超时时间(ti ...
- Cloudera Manager安装之Cloudera Manager 5.6.X安装(tar方式、rpm方式和yum方式) (Ubuntu14.04) (三)
见 Ubuntu14.04下完美安装cloudermanage多种方式(图文详解)(博主推荐) 欢迎大家,加入我的微信公众号:大数据躺过的坑 免费给分享 同时,大家可以关注我的个人 ...
- 如何在cmd窗口里快速且正确打开任意位置路径(各版本windows系统都适合)(图文详解)(博主推荐)
问题的由来 有时候,我们很苦恼,总是先系统键 + R,然后再去手动敲.尤其对win7系统比较麻烦 解决办法 方法一:复制路径(这点对win10系统做得好,直接可以复制) ,win7系统的话可能还需要设 ...
- Windows下SVN回滚到旧版本(TortoiseSVN)
当发现新提交的代码有问题,然后想将某个旧的版本作为最新的版本时,可以使用回滚, 操作步骤如下: 1. 签出(CheckOut)最新版本的代码到电脑中(不能做任何修改) 2. 执行TortoiseSVN ...
- spring mvc中的控制器方法中的参数从哪里传进来?
编写控制器方法的时候很奇怪,spring是怎么知道你控制器方法的参数类型,并且注入正确的对象呢? 比如下面这样 @RequestMapping(value="/register", ...
- HTML 三角符号
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- js&&jQuery实现省市区三级联动
代码参考了:https://codepen.io/anon/pen/WzyNQB;根据自己的需要修改了一下,挂个出处 1.前端页面代码 <html> <head> <me ...