很多人认为私有性是面向对象语言的应有的一部分。每个对象的状态应该是这个对象自己的事情。在一些面向对象的语言中,比如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()
print(acc1.getBalance()) -- 100 print(acc1.balance) -- nil

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

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

 function newAccount (initialBalance)
local self = { balance = initialBalance ,
LIM = } local withdraw = function (v)
self.balance = self.balance - v
end local extra = function ()
if self.balance > self.LIM then
return self.balance*0.10
else
return
end
end local deposit = function (v)
self.balance = self.balance + v
end local getBalance = function ()
return self.balance + extra() --[此处非self.extra()]
end return {
withdraw = withdraw,
deposit = deposit,
getBalance = getBalance,
-- extra = extra,
}
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

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

  1. 2015/9/28 Python基础(19):类的定制和私有性

    用特殊方法定制类前面我们讲了方法的两个重要方面:首先,方法必须在调用前被绑定(到它们相应类的某个实例中):其次,有两个特殊方法可以分别作为构造器和解构器的功能,分别名为__init__()和__del ...

  2. Rust中的模块及私有性控制

    好像没有其它语言的private, protected关键字,应了一个public关键字. mod plant { pub struct Vegetable { pub name: String, _ ...

  3. Lua语言中文手册 转载自网络

    Programming in LuaCopyright ® 2005, Translation Team, www.luachina.net Programming in LuaProgramming ...

  4. Lua学习笔记一

    学习了有一周多了.之前一直不想献丑,但还是记录下这个过程. 第1章  开发软件搭建 1. ubuntu 下lua安装 sudo apt-get install lua5.1 2.win下的环境搭建. ...

  5. Lua面向对象设计

    首先对于Lua语言,它没有打算被用来进行大型的程序设计,相反,Lua目标定于小型到中型的程序设计,通常是作为大型系统的一部分,所以它只提供了一套精简的元素,很多高级语言的概念都没有.这样Lua就成为了 ...

  6. Lua基础之table详解

    概要:1.table特性:2.table的构造:3.table常用函数:4.table遍历:5.table面向对象 原文地址:http://blog.csdn.net/dingkun520wy/art ...

  7. Lua面向对象设计(转)

    首先对于Lua语言,它没有打算被用来进行大型的程序设计,相反,Lua目标定于小型到中型的程序设计,通常是作为大型系统的一部分,所以它只提供了一套精简的元素,很多高级语言的概念都没有.这样Lua就成为了 ...

  8. lua的面向对象

    Lua中的table就是一种对象,但是如果直接使用仍然会存在大量的问题,见如下代码: Account = {balance = } function Account.withdraw(v) Accou ...

  9. Lua的面向对象程序设计

    Account={balance=} function Account.withdraw(self,v) self.balance=self.balance-v end a={balance=,wit ...

随机推荐

  1. 为什么我坚持学习C语言?

    c语言令无数人头疼,有意躲避! linux操作系统有c: glibc的c运行时库有c: mysql有c: php的底层有c: nosql层有c: 甚至其他的curl.nginx等等都有c: 每当问题追 ...

  2. gitlab安装过程总结

    gitlab总算搭建好了,今天下午完成了第一个工程的导入. 梳理下搭建的过程: 1.下载bitnami的一键安装包,并安装 注意设置权限为777,以免出现某文件写入错误的问题 2.配置邮件服务 分别修 ...

  3. IIS出现 分析器错误消息: 在应用程序级别之外使用注册为 allowDefinition='MachineToApplication' 的节是错误的

    这是因为发布的时候按了“生成部署包”

  4. Oracle中rownum和rowid的理解(转)

    本文转自地址http://www.linuxidc.com/Linux/2012-04/58300.htm rownum,rowid都叫伪列. 但是,rownum是逻辑上的编号,且其值总是从1开始,每 ...

  5. SA: 情感分析资源(Corpus、Dictionary)

    先主要摘自一篇中文Survey,http://wenku.baidu.com/view/0c33af946bec0975f465e277.html   4.2 情感分析的资源建设 4.2.1 情感分析 ...

  6. Python 性能优化——对象绑定

    不同函数调用方式对应不同的绑定次数: import profile class A: def f(self): pass def foo(): a = A() for i in range(10000 ...

  7. Django-数据模型

    修改model.py文件 from django.db import models # Create your models here. class Question(models.Model): q ...

  8. 搭建一个SSH项目框架的步骤

    1.导入jar包(38个) 2.配置文件 applicationContext,xml (beans.xml) (数据源.LocalSessionFactoryBean.事务管理器.事务通知.AOP切 ...

  9. css各项水平居中

    当被设置元素为块状元素时用text-align:center就不起作用了,这也分两种情况,定宽块状元素和不定宽块状元素. 一.定宽块状元素:快状元素的宽度width为固定值,之后我们可以将左右marg ...

  10. 3.一起来学hibernate之配置文件2

    之前的映射文件配置都是简单的.基础的配置,只涉及到单个javabean,对于单个javabean的增删改查都能很好的.简单的去完成. 但是知道简单配置远远不够,并不能完成很多复杂的情况,比如对象与对象 ...