What is the purpose of metatables in Lua (5.2) for OOP?

I am trying to understand how metadata works and why it is needed in Lua for creating classes and for inheritance. Each OOP example I found for Lua is slightly different from the last, but they always use meta tags, especially for the __index property. Here's how I implemented some simple inheritance:

 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() 

Output:

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

So, as far as I see, this works just fine. How would using metatables improve my design?

+4
source share
1 answer

No one says that metadata is needed for OOP. They are useful, but not important.

Meta tags allow you to hide data. I can very easily break all of your careful encoding:

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

It will also resolve other dubious constructs, such as storing other data in an object: dog.newVar = foo .

OOP is more than just inheritance. A good OOP should also include encapsulation to preserve the integrity of the object from accidental abuse. Metatables allow you to do this by using an empty table for the main table and filtering all the settings and going through the __index and __newindex . Thus, only an object can store data in the actual table. And only an object can get it if you do not provide explicit access.

+1
source

All Articles