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 ?