私有性(Privacy)

简介: 私有性(Privacy)

许多人认为,私有性(也被称为信息隐藏)是一门面向对象语言不可或缺的一部分;每个对象的在状态都应该由它自己控制。在一些诸如 C++Java 的面向对象语言中,我们可以控制一个字段(也被称为实例变量)或一个方法是否在对象之外可见。另一种非常流行的面向对象语言 Smalltalk ,则规定所有的变量都是私有的,而所有的方法都是公有的。第一种面向对象语言 Simula ,则不提供任何形式的私有性保护。


此前,我们所学的 Lua 语言中标准的对象实现方式没有提供私有性机制。一方面,这是使用普通结构(表)来表示对象所带来的后果;另一方面,这也是 Lua 语言为了避免冗余和人为限制所采取的方法。如果不想访问一个对象的内容,那就不要取访问就是了

一种常见的做法是把所有的私有名称的前面加上一个下划线,这样就能立刻区分出全局名称了。


不过,尽管如此, Lua 语言的另外一项设计目的是灵活性,它为程序员提供能够模拟许多不同机制的元机制。虽然在 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


首先,这个函数创建了一个用于保存对象内部状态的表,并将其存储在局部变量 self 中。然后,这个函数创建了对象的方法。最后,这个函数会创建并返回一个外部对象,该对象将方法名与真正的方法实现映射起来。这里的关键在于,这些方法不需要额外的 self 参数,而是直接访问 self 变量。由于没有了额外的参数,我们也就无需使用冒号语法来操作这些对象,而是可以像普通函数那样来调用这些方法:

acc1 = newAccount(100.00)
acc1.withdraw(40.00)
print(acc1.getBalance())    --> 60


这种设计给予了存储在表 self 中所有内容完全的私有性。当 newAccount 返回后,就无法直接访问这个表了,我们只能通过在 newAccount 中创建的函数来访问它。虽然我们的示例只把一个实例变量放到了私有表中,但还可以将一个对象中的所有私有部分都存入这个表。我们也可以定义私有方法,他们类似于公有方法但不放入接口中。例如,我们的账户可以给余额大于某个值的用户额外 10% 的信用额度,但是又不想让用户访问到这些计算细节,就可以将这个功能按照以下方法实现:

function newAccount(initialBalance)
  local self = {
    balance = initialBalance,
    LIM = 10000.00
  }
  local extra = function ()
    if self.balance > self.LIM then
      return self.balance * 0.10
    else
      return 0
    end
  end
  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 * extra()
  end
  return {
    withdraw = withdraw,
    deposit = deposit,
    getBalance = getBalance
  }
end


与前一个示例一样,任何用户都无法直接访问 extra 函数。

目录
相关文章
|
2月前
|
Linux 网络安全 API
【Azure 环境】当在Azure 环境中调用外部接口不通时,如何定位SSL Certificate Problem
【Azure 环境】当在Azure 环境中调用外部接口不通时,如何定位SSL Certificate Problem
|
2月前
|
网络协议
【Azure 应用服务】添加自定义域时,Domain ownership 验证无法通过 
【Azure 应用服务】添加自定义域时,Domain ownership 验证无法通过 
|
5月前
|
安全 网络安全 网络性能优化
认证方式总结(802.1x,PPPOE,IPOE,Portal,MAC认证)
认证方式总结(802.1x,PPPOE,IPOE,Portal,MAC认证)
184 3
|
物联网
Internet of Everything与Internet of Things:有什么区别?
除非您是专家,否则物联网(IoT)和万物互联(IoE)之间几乎没有什么区别。但是,后一个术语在语义上更广泛。 在本文中,我们将详细介绍为什么物联网软件开发公司相对很少使用术语IoE。
497 0
Internet of Everything与Internet of Things:有什么区别?
|
测试技术 网络虚拟化
|
网络安全 数据安全/隐私保护
|
算法 网络安全 数据安全/隐私保护