Lua 自己实现类Class代码,和高级用法

本文介绍了一种在Lua中实现面向对象编程的方法,包括类的创建、继承和方法重写等核心概念。通过具体示例展示了如何定义基类及派生类,并实现了方法覆盖。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Class代码实现:
[csharp]  view plain  copy
  1. function class(classname, super)  
  2.     local superType = type(super)  
  3.     local cls  
  4.   
  5.     if superType ~= "function" and superType ~= "table" then  
  6.         superType = nil  
  7.         super = nil  
  8.     end  
  9.   
  10.     if superType == "function" or (super and super.__ctype == 1) then  
  11.         -- inherited from native C++ Object  
  12.         cls = {}  
  13.   
  14.         if superType == "table" then  
  15.             -- copy fields from super  
  16.             for k,v in pairs(super) do cls[k] = v end  
  17.             cls.__create = super.__create  
  18.             cls.super    = super  
  19.         else  
  20.             cls.__create = super  
  21.             cls.ctor = function() end  
  22.         end  
  23.   
  24.         cls.__cname = classname  
  25.         cls.__ctype = 1  
  26.   
  27.         function cls.new(...)  
  28.             local instance = cls.__create(...)  
  29.             -- copy fields from class to native object  
  30.             for k,v in pairs(cls) do instance[k] = v end  
  31.             instance.class = cls  
  32.             instance:ctor(...)  
  33.             return instance  
  34.         end  
  35.   
  36.     else  
  37.         -- inherited from Lua Object  
  38.         if super then  
  39.             cls = {}  
  40.             setmetatable(cls, {__index = super})  
  41.             cls.super = super  
  42.         else  
  43.             cls = {ctor = function() end}  
  44.         end  
  45.   
  46.         cls.__cname = classname  
  47.         cls.__ctype = 2 -- lua  
  48.         cls.__index = cls  
  49.   
  50.         function cls.new(...)  
  51.             local instance = setmetatable({}, cls)  
  52.             instance.class = cls  
  53.             instance:ctor(...)  
  54.             return instance  
  55.         end  
  56.     end  
  57.   
  58.     return cls  
  59. end  
创建一个类
lua中
[csharp]  view plain  copy
  1. //定义名为 Shape 的基础类  
  2. local Shape = class("Shape")  
  3.   
  4.   
  5. //ctor() 是类的构造函数,在调用 Shape.new() 创建 Shape 对象实例时会自动执行  
  6. function Shape:ctor(shapeName)  
  7.     self.shapeName = shapeName  
  8.     printf("Shape:ctor(%s)", self.shapeName)  
  9. end  
  10.   
  11. //为 Shape 定义个名为 draw() 的方法  
  12. function Shape:draw()  
  13.     printf("draw %s", self.shapeName)  
  14. end  
  15.   
  16. // Circle 是 Shape 的继承类  
  17. local Circle = class("Circle", Shape)  
  18.   
  19.   
  20. function Circle:ctor()  
  21.     -- 如果继承类覆盖了 ctor() 构造函数,那么必须手动调用父类构造函数  
  22.     -- 类名.super 可以访问指定类的父类  
  23.     Circle.super.ctor(self, "circle")  
  24.     self.radius = 100  
  25. end  
  26.   
  27.   
  28. function Circle:setRadius(radius)  
  29.     self.radius = radius  
  30. end  
  31.   
  32.   
  33. // 覆盖父类的同名方法  
  34. function Circle:draw()  
  35.     printf("draw %s, raidus = %0.2f", self.shapeName, self.raidus)  
  36. end  
  37.   
  38.   
  39. --  
  40. local Rectangle = class("Rectangle", Shape)  
  41.   
  42. function Rectangle:ctor()  
  43.     Rectangle.super.ctor(self, "rectangle")  
  44. end  
  45.   
  46. --  
  47.   
  48. local circle = Circle.new()             -- 输出: Shape:ctor(circle)  
  49. circle:setRaidus(200)  
  50. circle:draw()                           -- 输出: draw circle, radius = 200.00  
  51.   
  52.   
  53. local rectangle = Rectangle.new()       -- 输出: Shape:ctor(rectangle)  
  54. rectangle:draw()                        -- 输出: draw rectangle  

高级用法

class() 除了定义纯 Lua 类之外,还可以从 C++ 对象继承类。比如需要创建一个工具栏,并在添加按钮时自动排列已有的按钮,那么我们可以使用如下的代码:
[csharp]  view plain  copy
  1. // 从 cc.Node 对象派生 Toolbar 类,该类具有 cc.Node 的所有属性和行为  
  2. local Toolbar = class("Toolbar", function()  
  3.     return display.newNode() -- 返回一个 cc.Node 对象  
  4. end)  
  5.   
  6. //构造函数  
  7. function Toolbar:ctor()  
  8.     self.buttons = {} -- 用一个 table 来记录所有的按钮  
  9. end  
  10.   
  11. //添加一个按钮,并且自动设置按钮位置  
  12. function Toolbar:addButton(button)  
  13.     // 将按钮对象加入 table  
  14.     self.buttons[#self.buttons + 1] = button  
  15.   
  16.     //添加按钮对象到 cc.Node 中,以便显示该按钮  
  17.     // 因为 Toolbar 是从 cc.Node 继承的,所以可以使用 addChild() 方法  
  18.     self:addChild(button)  
  19.   
  20.     // 按照按钮数量,调整所有按钮的位置  
  21.     local x = 0  
  22.     for _, button in ipairs(self.buttons) do  
  23.         button:setPosition(x, 0)  
  24.         -- 依次排列按钮,每个按钮之间间隔 10 点  
  25.         x = x + button:getContentSize().width + 10  
  26.     end  
  27. end  
  28.   
  29. class() 的这种用法让我们可以在 C++ 对象基础上任意扩展行为。既然是继承,自然就可以覆盖 C++ 对象的方法:  
  30.   
  31. function Toolbar:setPosition(x, y)  
  32.     // 由于在 Toolbar 继承类中覆盖了 cc.Node 对象的 setPosition() 方法  
  33.     // 所以我们要用以下形式才能调用到 cc.Node 原本的 setPosition() 方法  
  34.     getmetatable(self).setPosition(self, x, y)  
  35.   
  36.     printf("x = %0.2f, y = %0.2f", x, y)  
  37. end  

**注意:** Lua 继承类覆盖的方法并不能从 C++ 调用到。也就是说通过 C++ 代码调用这个 cc.Node 对象的 setPosition() 方法时,并不会执行我们在 Lua 中定义的 Toolbar:setPosition() 方法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值