面向对象编程
   对象的实现
    在lua中table就是一种对象
        1.有自己的状态
        2.有自己的唯一标识self
        3.有自己的生命周期
    使用table可以自己实现面向对象的几乎所有特性
    把函数定义在table中,并使用t.func的形式访问,如同方法调用
    Account = {balance=0}
    function Account.withdraw(v)
        Account.balance = Account.ballance - v
    end
    但在函数中使用全局的Account是一个不好的习惯
    在lua中使用面向对象方式编程时尽量使用self和t:func的形式    
    带有标识自身对象的方法定义:
    function Account.withdraw(self, v)
    同上的语法糖定义:
    function Account:withdraw(v)
    带有标识自身对象的方法调用:
    a1.withdraw(a1, v)
    同上的语法糖定义:
    a1:withdraw(v)
    使用":"会把自身当做每一个参数隐式的传入
    使用self是面向对象编程的一大核心,很多语言为程序员隐藏了这个参数
    self在C++中就相当于this指针
   类的实现    
    在lua中没有类的概念,但可以自己来实现
    function Account:new(o)
        o = o or {} --如果用户没有提供table,则创建一个
        setmetatable(o, self)
        self.__index = self
        return o
    end
    当使用new函数来创建对象后(其实就是创建一个新的table),所有的访问都会从Account这个table里找
    这种情况就相当于Account是一个类,也可以说是一个原型模具,所有新创建的table都拥有他的属性和方法
    a = Account:new{balance=0}
    a:deposit(100.00)
    由于deposit在新创建的table a里没有定义
    因此通过它的元表__index来查找,a的元表是Account,
    因此会调用Account的deposit方法,但self传入的是a
    这就实现了a继承了Account的方法deposit
    在这里也看到了使用self来标识调用对象的好处
   继承和派生
    sa = Account:new()
    s = sa:new{limit=1000.00}
    第一行sa继承了Account,sa的元表是Account,找不到的方法就去Account里去找
    第二行s继承了sa,这里的new是Account的方法但传入的self是sa,
    致使s的元表是sa而sa的元表又是Account
    所以一层一层的继承了下去,并且在每一层的派生table里都可以定义重载方法和新的方法
    在lua里的可以实现多重继承,就是使元表的__index指向一个函数,然后自行判断并处理
   私密性
    使用table来实现面向对象的编程方式,几乎可以实现所有面向对象的编程特性
    但它没有也不想去实现的就是对象的私密性,也就是c++里的private、public、protected
    这与lua设计的初衷有关,lua定位于小型的程序开发,参与一个工程的人不会很多,自行约束
    非要实现私密性的话lua也不是不能,只是不能再使用table和元表的方式了
    可以使用函数闭包来实现私密性:
    function newAccount(init)
         local self = {blance=init}
         local withdraw = function(v)
             self.balance = self.balance - v
         end
         local deposit = function(v)
             self.balance = self.balance + v
         end
         return{withdraw = withdraw, deposit = deposit}
    end
    在闭包里定义一个table的upvalue,然后把所有闭包函数都定义在这里table里,
    然后返回这个table,用key访问内部方法
    使用闭包实现对象的方式比用table效率高并实现了绝对的私密性,但无法实现继承,相当于简单的小对象
    甚至可以在闭包里仅定义一个方法,然后通过key来判断调用是什么方法
    Tcl/Tk对它的窗口部件就使用这种方法
 

lua学习笔记(十一)的更多相关文章

  1. [转]LUA 学习笔记

    Lua 学习笔记 入门级 一.环境配置 方式一: 1.资源下载http://www.lua.org/download.html 2.用src中的源码创建了一个工程,注释调luac.c中main函数,生 ...

  2. Lua 学习笔记(一)

    Lua学习笔记 1.lua的优势 a.可扩张性     b.简单     c.高效率     d.和平台无关 2.注释 a.单行注释 --        b.多行注释 --[[  --]] 3.类型和 ...

  3. Lua学习笔记6:C++和Lua的相互调用

        曾经一直用C++写代码.话说近期刚换工作.项目组中的是cocos2dx-lua,各种被虐的非常慘啊有木有.     新建cocos2dx-lua项目.打开class能够发现,事实上就是C++项 ...

  4. Lua学习笔记4. coroutine协同程序和文件I/O、错误处理

    Lua学习笔记4. coroutine协同程序和文件I/O.错误处理 coroutine Lua 的协同程序coroutine和线程比较类似,有独立的堆栈.局部变量.独立的指针指令,同时又能共享全局变 ...

  5. (转)Lua学习笔记1:Windows7下使用VS2015搭建Lua开发环境

    Lua学习笔记1:Windows7下使用VS2015搭建Lua开发环境(一)注意:工程必须添加两个宏:“配置属性”/“C或C++”/“预处理器”/“预处理器定义”,添加两个宏:_CRT_SECURE_ ...

  6. python3.4学习笔记(十一) 列表、数组实例

    python3.4学习笔记(十一) 列表.数组实例 #python列表,数组类型要相同,python不需要指定数据类型,可以把各种类型打包进去#python列表可以包含整数,浮点数,字符串,对象#创建 ...

  7. Go语言学习笔记十一: 切片(slice)

    Go语言学习笔记十一: 切片(slice) 切片这个概念我是从python语言中学到的,当时感觉这个东西真的比较好用.不像java语言写起来就比较繁琐.不过我觉得未来java语法也会支持的. 定义切片 ...

  8. Lua学习笔记:面向对象

    Lua学习笔记:面向对象 https://blog.csdn.net/liutianshx2012/article/details/41921077 Lua 中只存在表(Table)这么唯一一种数据结 ...

  9. Lua学习笔记(二):基本语法

    Lua学习指南:http://www.lua.org/manual/ 首先我们要明确的一点是:在Lua中,除了关键字外一切都是变量. Lua关键字 可以查看这个地址:http://www.lua.or ...

  10. JavaScript权威设计--JavaScript函数(简要学习笔记十一)

    1.函数调用的四种方式 第三种:构造函数调用 如果构造函数调用在圆括号内包含一组实参列表,先计算这些实参表达式,然后传入函数内.这和函数调用和方法调用是一致的.但如果构造函数没有形参,JavaScri ...

随机推荐

  1. 日志采集客户端 filebeat 安装部署

    linux----------------1. 下载wget https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-5.5.1- ...

  2. USACO 4.4.2 追查坏牛奶 oj1341 网络流最小割问题

    描述 Description 你第一天接手三鹿牛奶公司就发生了一件倒霉的事情:公司不小心发送了一批有三聚氰胺的牛奶.很不幸,你发现这件事的时候,有三聚氰胺的牛奶已经进入了送货网.这个送货网很大,而且关 ...

  3. ACM集训日志——day1——15.7.8

    UVA 11292 The Dragon of Loowater 题意 给n个头,m个骑士,骑士有能力值x,代表他可以砍掉一个直径不超过x的头,并且佣金为x,求要砍掉所有的头,需要的最少佣金是多少. ...

  4. [POI2010]Beads

    题目大意: 给定一个长度为$n(n\leq200000)$的串$S_{1\sim n}$,选择一个$l$,从$S_1$开始,将$S$分为连续的若干段,使得每一段长度为$l$.令$k$为分出来不同的子串 ...

  5. Java类的定义及其实例化

    如果你不了解类和对象的概念,请猛击这里:Java类和对象的概念 类必须先定义才能使用.类是创建对象的模板,创建对象也叫类的实例化. 下面通过一个简单的例子来理解Java中类的定义: public cl ...

  6. DOTween教程

    参考自DOTween官方文档: DOTween起始上手起来很快,当然前提也是用心看一下哈. > 可以在Unity AssetStore下载得到. 使用方法: 准备: 在导入DOTween后,你需 ...

  7. VUE的进阶 标签属性数据绑定和拼接

    在vue官网把文档扫了一遍后,就开始写网站项目了,没有设计,就百度里找了一个h5的助赢软件的网站把他copy下来,想想有点坏了,接着把内容改改吧.首先开始做一个列表展示vue实例好后,给对象添加默认数 ...

  8. 解决413 Request Entity Too Large

    修改nginx配置    这是最简单的一个做法,着报错原因是nginx不允许上传配置过大的文件,那么件把nginx的上传大小配置调高就好. 1.打开nginx主配置文件nginx.conf,一般在/u ...

  9. Docker删除全部镜像和容器

    杀死所有正在运行的容器 docker kill $(docker ps -a -q) 删除所有已经停止的容器 docker rm $(docker ps -a -q) 删除所有未打 dangling ...

  10. Android 常驻与很驻型广播的差别,及ListView优化,Android新手基本知识巩固

    1.常驻型广播  常驻型广播,当你的应用程序关闭了,假设有广播信息来,你写的广播接收器相同的能接受到.  他的注冊方式就是在你的应用程序中的AndroidManifast.xml进行注冊. 通常说这样 ...