Je vais avoir du mal à grokking classes dans Lua . Un googling sans fruit m'a conduit aux idées sur les méta-tables et implicite que des bibliothèques tierces sont nécessaires pour simuler / écrire des cours.
Voici un échantillon (juste parce que j'ai remarqué que j'obtiens de meilleures réponses lorsque je fournis un code d'échantillon): p>
--Everything is a table ElectronicDevice = {}; --Magic happens mt = {__index=ElectronicDevice}; --This must be a constructor function ElectronicDeviceFactory () -- Seems that the metatable holds the fields return setmetatable ({isOn=true}, mt) end -- Simulate properties with get/set functions function ElectronicDevice:getIsOn() return self.isOn end function ElectronicDevice:setIsOn(value) self.isOn = value end function ElectronicDevice:Reboot() self.isOn = false; self:ResetHardware(); self.isOn = true; end function ElectronicDevice:ResetHardware() print('resetting hardware...') end Router = {}; mt_for_router = {__index=Router} --Router inherits from ElectronicDevice Router = setmetatable({},{__index=ElectronicDevice}); --Constructor for subclass, not sure if metatable is supposed to be different function RouterFactory () return setmetatable ({},mt_for_router) end Modem ={}; mt_for_modem = {__index=Modem} --Modem inherits from ElectronicDevice Modem = setmetatable({},{__index=ElectronicDevice}); --Constructor for subclass, not sure if metatable is supposed to be different function ModemFactory () return setmetatable ({},mt_for_modem) end function Modem:WarDialNeighborhood(areaCode) cisco = RouterFactory(); --polymorphism cisco.Reboot(); --Call reboot on a router self.Reboot(); --Call reboot on a modem if (self.isOn) then self:StartDialing(areaCode) end; end function Modem:StartDialing(areaCode) print('now dialing all numbers in ' .. areaCode); end testDevice = ElectronicDeviceFactory(); print("The device is on? " .. (testDevice:getIsOn() and "yes" or "no") ); testDevice:Reboot(); --Ok testRouter = RouterFactory(); testRouter:ResetHardware(); -- nil value testModem = ModemFactory(); testModem:StartDialing('123'); -- nil value
7 Réponses :
Il y a plusieurs façons de le faire, mais c'est comme ça que je fais (mis à jour avec un tir à l'héritage): Je ne mettez pas en place de privé, protégé, etc. Bien que ce soit possible . P> P>
Il est vraiment facile de faire de l'oop en forme de classe à Lua; Il suffit de mettre toutes les «méthodes» dans le champ code> index code> d'une métables: personnellement, je n'ai jamais eu besoin d'héritage, donc ce qui précède est suffisant pour moi. Si ce n'est pas suffisant, vous pouvez définir une métavère pour la table des méthodes: p> Notez que vous initialisez Remplacez le < Code> routeur = {} code> avec le routeur routeur code> et construire
mt_for_router code> de ceci; mais vous réaffectez
routeur code> à une nouvelle table, tandis que
mt_for_router code> pointe toujours sur l'original
routeur code>. p>
setmettable ({}, {__ index = electronddevice}) code> (avant le
mt_for_router code> initialisation). P> p>
La façon dont j'ai aimé le faire était en mettant en œuvre une fonction clone (). vous définissez ensuite une classe comme une table: p> pour l'instancier ou en dériver, vous utilisez clone () et Vous pouvez remplacer les choses en les transmettant dans une autre table (ou tables) comme mix-ins p> à appeler, vous utilisez la syntaxe: p> qui imprimera: p> Pour dériver une sous-classe, vous définissez essentiellement un autre objet prototype: P>
Notez que c'est pour Lua 5.0. Je pense que 5,1 a des constructions orientées objet plus intégrées. BigThing = clone(Thing, {
-- and override stuff.
foo = function(self, x)
print("hello");
end
}
Votre code mis à jour est Wordy, mais devrait fonctionner. sauf fort>, vous avez une faute de frappe qui brise l'un des métabiles: doit lire p> le Fragment existant a rendu le modem code> métables code> une matrice où le premier élément était presque certainement nul (la valeur habituelle de Le Lua Wiki Description aura du sens après avoir grokked Metables un peu plus. Une chose qui aide à construire une petite infrastructure permettant de faciliter les modèles habituels. P> Je recommanderais également de lire le chapitre sur OOP dans PIL A >. Vous voudrez également relire les chapitres sur les tables et les métabiles aussi. De plus, j'ai lié à la copie en ligne de la 1ère édition, mais à posséder une copie du 2e est fortement recommandée. Il y a aussi quelques articles dans le Lua Gems livre qui se rapportent. Il est également recommandé. P> p> _g .__ index code> sauf si vous utilisez
strict.lua < / code> ou quelque chose de similaire) et le deuxième élément est
électroniquedevice code>. p>
Voici un exemple de transcription littéral de votre code, avec une bibliothèque code> de classe code> utile qui pourrait être déplacée dans un autre fichier.
Ceci n'est en aucun cas une implémentation canonique de classe code>; N'hésitez pas à définir votre modèle d'objet, mais vous le souhaitez. P>
BaseClass = {}
BaseClass.index = {}
BaseClass.metatable = {__index = BaseClass.index}
DerivedClass = {}
DerivedClass.index = setmetatable({}, {__index = BaseClass.index})
DerivedClass.metatable = {__index = DerivedClass.index}
Si vous ne voulez pas réinventer la roue, une belle bibliothèque Lua met en œuvre plusieurs modèles d'objets. C'est ce qu'on appelle boucle . P>
Une autre approche simple pour la sous-classe Vous pouvez toujours utiliser les fonctions de Superclass même si écrasé p> n'oubliez pas de Utilisez un point lorsque vous passez à la fonction Superclass P> P>
Avez-vous lu Ceci ?