当前位置 : 主页 > 网络编程 > lua >

元数据在Lua(5.2)中为OOP服务的目的是什么?

来源:互联网 收集:自由互联 发布时间:2021-06-23
我正在努力理解metatable如何工作以及为什么在Lua中需要它们来创建类和继承.我发现Lua的每个OOP示例都与上一个略有不同,但它们总是使用metatable,特别是__index属性.以下是我实现一些简单
我正在努力理解metatable如何工作以及为什么在Lua中需要它们来创建类和继承.我发现Lua的每个OOP示例都与上一个略有不同,但它们总是使用metatable,特别是__index属性.以下是我实现一些简单继承的方法:

Animal = {}

function Animal.New()
  local self = {}
  self.sName = "Generic Animal"

  self.GetName = function(self)
    return self.sName
  end

  self.Speak = function(self)
    -- Do nothing, abstract function
  end

  return self
end

Dog = {}

function Dog.New()
  local self = Animal.New()
  self.sName = "Dog"

  self.Speak = function(self)
    print("Bark!")
  end

  return self
end

Labrador = {}

function Labrador.New()
  local self = Dog.New()
  self.sName = "Labrador"
  return self
end

Chihuahua = {}

function Chihuahua.New()
  local self = Dog.New()
  self.sName = "Chihuahua"

  self.Speak = function(self)
    print("Yap yap!")
  end

  return self
end

-- Test --

l = Labrador.New()
print(l:GetName())
l:Speak()

c = Chihuahua.New()
print(c:GetName())
c:Speak()

d = Dog.New()
print(d:GetName())
d:Speak()

a = Animal.New()
print(a:GetName())
a:Speak()

输出:

Labrador
Bark!
Chihuahua
Yap yap!
Dog
Bark!
Generic Animal

所以据我所知,这很好用.如何使用metatables改进我的设计?

没有人说OOP需要metatables.它们很有用,不是必需的.

Metatables允许您隐藏数据.我可以很容易地打破你所有的细致编码:

local dog = Chihuahua.New()
dog.sName = nil --Oops.
dog.GetName = nil --Oops.

它还允许其他可疑的构造,例如在对象中存储其他数据:dog.newVar = foo.

OOP不仅仅是继承.良好的OOP也应该包含encapsulation,以保持物体的完整性,防止意外误用. Metatables允许您通过使用主表的空表并过滤所有设置并通过__index和__newindex元方法来完成此操作.这样,只有对象可以在实际表中存储数据.除非您提供显式访问权限,否则只有对象可以检索它.

网友评论