lua的私有性(privacy)

  很多人认为私有性是面向对象语言的应有的一部分。每个对象的状态应该是这个对象自己的事情。在一些面向对象的语言中,比如C++和Java你可以控制对象成员变量或者成员方法是否私有。其他一些语言比如Smalltalk中,所有的成员变量都是私有,所有的成员方法都是公有的。第一个面向对象语言Simula不提供任何保护成员机制。

  如前面我们所看到的Lua中的主要对象设计不提供私有性访问机制。部分原因因为这是我们使用通用数据结构tables来表示对象的结果。但是这也反映了后来的Lua的设计思想。Lua没有打算被用来进行大型的程序设计,相反,Lua目标定于小型到中型的程序设计,通常是作为大型系统的一部分。典型的,被一个或者很少几个程序员开发,甚至被非程序员使用。所以,Lua避免太冗余和太多的人为限制。如果你不想访问一个对象内的一些东西就不要访问(If you do not want to access something inside an object, just do not do it.)。

  然而,Lua的另一个目标是灵活性,提供程序员元机制(meta-mechanisms),通过他你可以实现很多不同的机制。虽然Lua中基本的面向对象设计并不提供私有性访问的机制,我们可以用不同的方式来实现他。虽然这种实现并不常用,但知道他也是有益的,不仅因为它展示了Lua的 一些有趣的角落,也因为它可能是某些问题的很好地解决方案。设计的基本思想是,每个对象用两个表来表示:一个描述状态;另一个描述操作(或者叫接口)。对 象本身通过第二个表来访问,也就是说,通过接口来访问对象。为了避免未授权的访问,表示状态的表中不涉及到操作;表示操作的表也不涉及到状态,取而代之的 是,状态被保存在方法的闭包内。例如,用这种设计表述我们的银行账号,我们使用下面的函数工厂创建新的对象:

function newAccount (initialBalance)
    local self = { balance = initialBalance }
    local withdraw = function (v)
       self.balance = self.balance - v
    end

    local deposit = function (v)
       self.balance = self.balance + v
    end

    local getBalance = function ()
        return self.balance
    end

    return {
       withdraw = withdraw,
       deposit = deposit,
       getBalance = getBalance
    }
end

acc1 = newAccount(100.00)
acc1.withdraw(40.00)

print(acc1.getBalance())   -- 60
acc1.deposit(40)
print(acc1.getBalance())   -- 100

print(acc1.balance)        -- nil

  首先,函数创建一个表用来描述对象的内部状态,并保存在局部变量self内。然后,函数为对象的每一个方法创建闭包(也就是说,嵌套的函数实例)。最后,函数创建并返回外部对象,外部对象中将局部方法名指向最终要实现的方法。这儿的关键点在于:这些方法没有使用额外的参数self,代替的是直接访问self。因为没有这个额外的参数,我们不能使用冒号语法来访问这些对象。函数只能像其他函数一样调用:   acc1.deposit(40)     acc1.getBalance()

  这种设计实现了任何存储在self表中的部分都是私有的,newAccount返回之后,没有什么方法可以直接访问对象,我们只能通过newAccount中定义的函数来访问他。虽然我们的例子中仅仅将一个变量放到私有表中,但是我们可以将对象的任何的部分放到私有表中。我们也可以定义私有方法,他们看起来象公有的,但我们并不将其放到接口中。例如,我们的账号可以给某些用户取款享有额外的10%的存款上限,但是我们不想用户直接访问这种计算的详细信息,我们实现如下:

 1 function newAccount (initialBalance)
 2     local self = { balance = initialBalance ,
 3                    LIM = 1314 }
 4
 5     local withdraw = function (v)
 6        self.balance = self.balance - v
 7     end
 8
 9     local extra = function ()
10        if self.balance > self.LIM then
11            return self.balance*0.10
12        else
13            return 0
14        end
15     end
16
17     local deposit = function (v)
18        self.balance = self.balance + v
19     end
20
21     local getBalance = function ()
22         return self.balance + extra()  --[此处非self.extra()]
23     end
24
25     return {
26        withdraw = withdraw,
27        deposit = deposit,
28        getBalance = getBalance,
29        -- extra = extra,
30     }
31 end

       这样,对于用户而言就没有办法直接访问extra函数了;如此 也就实现lua private function。

      使用table来实现面向对象的编程方式,几乎可以实现所有面向对象的编程特性

但它没有也不想去实现的就是对象的私密性,也就是c++里的private、public、protected

这与lua设计的初衷有关,lua定位于小型的程序开发,参与一个工程的人不会很多,自行约束

非要实现私密性的话lua也不是不能,只是不能再使用table和元表的方式了

  它可以通过如上述所写方方式实现,在闭包里定义一个table的upvalue,然后把所有闭包函数都定义在这里table里,

然后返回这个table,用key访问内部方法

  使用闭包实现对象的方式比用table效率高并实现了绝对的私密性,但无法实现继承,相当于简单的小对象

甚至可以在闭包里仅定义一个方法,然后通过key来判断调用是什么方法

  Tcl/Tk对它的窗口部件就使用这种方法

原文出自: (Here)   参考 Here

时间: 2024-11-10 01:12:53

lua的私有性(privacy)的相关文章

Lua学习笔记一

学习了有一周多了.之前一直不想献丑,但还是记录下这个过程. 第1章  开发软件搭建 1. ubuntu 下lua安装 sudo apt-get install lua5.1 2.win下的环境搭建. 我选择的是Lua For Windows.一键安装.保存为LUA格式即可运行 预计在Linux下 开发工具 用 sublime_text,实际使用notepadqq,个人喜好无所谓. 第1章  语法学习 1.1  语法学习 Lua -i filename 开启调试. dofile (“filenam

Lua面向对象设计(转)

首先对于Lua语言,它没有打算被用来进行大型的程序设计,相反,Lua目标定于小型到中型的程序设计,通常是作为大型系统的一部分,所以它只提供了一套精简的元素,很多高级语言的概念都没有.这样Lua就成为了一个既简单又灵活的轻量级语言,但是基本上高级语言中的大多数机制都可以在现有Lua的基础上加以实现. 面向对象的基础是类,但Lua中没有提供类的概念,所以我们需要利用Lua现有的机制来实现类似于类的有关oop的一整套概念.基本方案是使用table来实现类机制,并且结合使用self参数和冒号操作.我们先

[Lua]Lua的面向对象程序设计

Lua中的表不仅在某种意义上是一种对象.像对象一样,表也有状态(成员变量):也有与对象的值独立的本性,特别是拥有两个不同值的对象(table)代表两个不同的对象:一个对象在不同的时候也可以有不同的值,但他始终是一个对象:与对象类似,表的生命周期与其由什么创建.在哪创建没有关系. local Account = {balance = 0} function Account.withdraw(v) Account.balance = Account.balance - v end --调用方法如下:

Lua总结

ref http://book.luaer.cn/ 基础 弱类型,没有类型定义 解释型语言,但是会通过编译器先编译成中间码然后再执行 字符串的处理:用table保存,最后table.concat(t, "\n") .. "\n".防止..引起的性能问题 注释: -- 块注释:-[[ ]] 没有++,+= 打印:print(a, b, c, "", 1) 字符串:'或者"均可 或者[[包含'和"]] 不需要声明类型,语句结束不需

Lua-简洁、轻量、可扩展的脚本语言

转自:http://rmingwang.com/The-Programming-Language-Lua.html 1. 一.Lua安装及常用库的安装 2. 1.1 Ubuntu $ sudo apt-get install lua5.2 3. 1.2 OS X $ brew install lua luarocks # luarocks是lua的模块管理工具 $ sudo ln -s /usr/bin/make /usr/bin/gmake # 解决 sh: gmake: command no

【FacebookSDK学习笔记】FacebookSDK控制面板详细说明

1.Dashboard控制面板 App ID和App Secret为创建此应用时自动生成的,想开发facebook的程序就必须要申请到它的的appid和secret .Facebook 使用它们来识别应用程序.请保持这些信息的私有性,不要让其他开发人员使用它们,因为这些用户会在您不知道的情况下恶意使用这些信息. 1.1.点击Getting Started,在弹出的窗口选择Android平台或其他.(这里只展示Android) 1.2.下载facebook sdk并导入Facebook SDK 1

CentOS下开启IPv6

CentOS新版本均正常开启了IPv6,如果没有开启,可以按以下方式开启: 开启服务器的IPV6服务 # 打开配置文件 [[email protected] ~]# vi /etc/sysctl.conf # 修改为下面的状态 net.ipv6.conf.all.disable_ipv6 = 0 net.ipv6.conf.default.disable_ipv6 = 0 net.ipv6.conf.lo.disable_ipv6 = 0 #生效IPv6配置 [[email protected]

『ENGLISH』

以A字母开头的词汇 英文 中文 abstract module 抽象模组 access 访问.存取 access control 存取控制 access control information 存取控制资讯 access mechanism 存取机制 access rights 存取权限 accessibility 无障碍性 accessibility information 无障碍网页资讯 accessibility problem 无障碍网页问题 accessible 无障碍的 access

关于commonjs,AMD,CMD之间的异同

1.简介 随着前端业务复杂度的增加,模块化成为一个大的趋势.而在ES6还未被浏览器所支持的情况下,commonjs作为ES6中标准模块加载方案,在客服端中的支持情况并不好,现在在客服端中有2中模块化的解决方案,CMD和AMD,他们的代表分别为seajs和requirejs.这篇文章主要介绍我对commonjs.AMD以及CMD的理解. 2.commonJS commonjs的目标是制定一个js模块化的标准,它的目标制定一个可以同时在客服端和服务端运行的模块.这些模块拥有自己独立的作用域,也可以向