Lua类和类继承实现

Lua本身是不能像C++那样直接实现继承,但我们可以用万能的table表来实现。

以下我总结了三种方式的类以及继承的实现

第一、官方的做法,使用元表实现 原理参照《Programming in lua》

  Object.lua  

Object = {class_id = 0}
function Object:new(o)
    o = o or {}
    setmetatable(o,self) -- 对象o调用不存在的成员时都会去self中查找,而这里的self指的就是Object
    self.__index = self
return o
end

---以下我们创建对象来测试以下local o1 = Object:new()o1.class_id = 11;
local o2 = Object:new()o2.class_id = 22;

以上我们就利用元表实现了一个类,但这个类没有任何行为,以下我们继承上面的类

DisplayObject.lua

DisplayObject = Object:new()
-- 现在为止,DisplayObject只是Object的一个实例,注意以下代码

D = DisplayObject:new(width = 100,height = 50)

-- DisplayObject从Object继承了new方法,当new执行的时候,self参数指向DisplayObject。所以,D的metatable是DisplayObject,__index 也是DisplayObject。这样,D继承了DisplayObject,后者继承了Object。

---在Lua中面向对象有趣的一个方面是你不需要创建一个新类去指定一个新的行为。

第二、复制表方式

我们同样使用上面的Object,换种写法

--Lua中的面向对象
--[[
  复制表方式面向对象
  参数为一张表,通过遍历这张表取值,赋给一张空表,最后返回新建的表,来达到克隆表
]]
function cloneTab(tab)
    local ins = {}
    for key, var in pairs(tab) do
        ins[key] = var
    end
    return ins
end  

Object = {class_id = 1}

function Object.new()  local o = cloneTab(Object)  return oend

-- 使用这个类local p = Object.new()

继承实现

DisplayObject.lua
--[[
  复制表
  第一参数是目标表,第二个参数是需要复制的表
  通过遍历tab来取值将它赋值到目标表中
]]
function copy(dist,tab)
    for key, var in pairs(tab) do
        dist[key] = var
    end
end 

DisplayObject = {}

function DisplayObject.new()
    local ss = Object.new()
    copy(ss,DisplayObject)
    return ss
endlocal p1 = DisplayObject.new()

第三,使用函数闭包的形式实现面向对象

--以函数闭包的形式实现面向对象  

--定义一个方法,函数闭包实现一个类的概念
function People(name)
    local self = {}
  --初始化方法,私有的
    local function init()
        self.name = name
    end  

    self.sayHi = function ()
        print("Hello "..self.name)
    end  

  --调用初始化
    init()
    return self
end  

--实例化一个对象
local p = People("ZhangSan")
p:sayHi()  

--函数闭包的形式实现类继承
function Man(name)
    local self = People(name)  

--  local function init()
--
--  end  

    self.sayHello = function ()
        print("Hi "..self.name)
    end  

    return self
end  

local m = Man("Lisi")
--m:sayHello()
m:sayHi()

PS;关于继承类,cocos2d-x v3版本提供一个更好更便捷的方式来实现。使用class全局方法创建

require "Object"

GameObject = class("GameObject",function ()
    return Object:new()
end)

function GameObject:create()
    return GameObject.new()
end-- 以上就实现了一个继承过程

在cocos引擎源代码下有extern.lua这个文件,里面就声明了class这个方法

时间: 2024-10-11 02:51:55

Lua类和类继承实现的相关文章

lua中基类和“继承机制”

基类:基类定义了所有对于派生类来说普通的属性和方法,派生类从基类继承所需的属性和方法,且在派生类中增加新的属性和方法. 继承:继承是C++语言的一种重要机制,它允许在已定义的类的基础上产生新类. lua基类和C++基类极为相似,但是lua中却没有继承这一说,更没有所谓的派生类.lua只能通过一种行为(元表)来模拟C++继承这一方法. 元表:lua中提供的元表是用于帮助lua数据变量完成某些非预定义功能的个性化行为,当它做某一种操作,然而self表中却没有定义实现这种操作的方法,那么为了实现这一操

Lua的面向对象——类和继承

本文转载于:http://www.benmutou.com/archives/1791 终于来了,在Lua中的面向对象编程,相信目前学习Lua的大部分人都是为了开发手机网游吧.而且基本都是奔着脚本语言的热更新特性去的,所以全脚本开发变得十分流行. 对于普及不太广的Lua(相对于C++.Java等主流语言),需要短时间上手开发游戏,对新手而言不算简单.所以大家才更习惯于继续用面向对象思想去折腾Lua吧~ 好了,不唠叨了,我最不喜欢唠叨了.(小若:是是是,你一点都不唠叨,赶紧开讲!) 1.类的对象

【python】-- 类的多继承、经典类、新式类

继承知识点补充 在python还支持多继承,但是一般我们很少用,有些语言干脆就不支持多继承,有多继承,就会带来两个概念,经典类和新式类. 一.多继承 之前我们都是讲的单继承,那么什么是多继承呢?说白了,就是:子类可以继承多个父类,就叫多继承. class SchoolMember(object): #SchoolMember类 '''学校成员基类''' def tell(self): print("the schoolmeber is tell...") class School(ob

面向对象【day07】:类的属性-继承-经典类

本节内容 类的公有属性 析构函数 类的继承 新式类和经典类 一.类的公有属性 一.概述 前面我们讲了类的私有属性,现在我们来说说类的公有属性,这边很容易被人弄混淆,有人觉的,在__init__()构造方法中,除了私有属性,其他的都是公有属性了,其实这是一个错误的结论,并不是定义在__init__()初始化方法中的属性是公有属性(除私有属性),那什么是公有属性呢?揭起了大家的好奇心. 定义:指的是所属这个类的所有对象,都可以访问的属性,叫做公有属性. 二.公有属性 2.1 定义 说明:在类中直接定

python_way.day7 模块(configparser,xml,shutil,subprocess)、面向对象(上)(创建类,类的构成,函数式编程与面向对象编程的选择,类的继承)

python_way.day7 1.模块 configparser,xml,shutil,subprocess 2.面向对象(上) 创建类,类的构成,函数式编程与面向对象编程的选择,类的继承 1.模块 configparser 用于处理特定格式的文件,其本职上使用open来操作,只能是  [test1] 特定的格式 [test1] k1 = 123 k2 = True [test2] k1 = 123 k2 = v1 文件内容 1.获取 import configparser #打开文件找到文件

038类和对象:继承

继承1.继承简单使用:   格式:class DerivefClassName(BaseClassName):         BaseClassName:为基类.父类或超类         DerriverfClassName:为子类   如:>>> class Parent:             #父类       ...     def hello(self):       ...         print("father")       ...     

黑马程序员--oc 类的封装 继承 和多态

------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------- 成员变量的命名规范: 成员变量名要以 _开头 作用: 1.可以让成员变量和get方法的名称区分开 2.可以和局部变量区分开,一看到以_开头的变量一般都是成员变量 封装: 在定义成员变量时,尽量不要用@public 这种写法 ,而是使用set方法和get方法 @interface Student : NSObject { int _age; } /* set方法: 作用:提供一个方法给外界设置成

C#与Java对比学习:类型判断、类与接口继承、代码规范与编码习惯、常量定义(转载)

C#与Java对比学习:类型判断.类与接口继承.代码规范与编码习惯.常量定义 类型判断符号: C#:object a;  if(a is int) { }  用 is 符号判断 Java:object a; if(a instanceof Integer) { } 用 instanceof 符号判断 类与接口的继承: C#:public class MDataRow : List<MDataCell>, IDataRecord, ICustomTypeDescriptor Java:publi

代码复用原则:合理使用类组合和类继承

继承和组合都可以达到代码复用的目的,但是组合比继承更具灵活性.组合是通过引用已有类(一般为抽象类)或接口来实现复用的组合在运行时通过多态可以动态替换被组合的对象.继承是通过以子类继承父类方式来使父类的非私有成员可以被其子类使用.继承在类编译时就确定了继承来的方法和 属性,无法在运行时动态改变从父类继承来的方法.如果继承得来的某个方法在子类中不适用,这时就需要重写该方 法.而这样又很有可能违反LSP设计原则.如果父类非私有成员发生了改变那么继承他的子类也不得不发生改变父类改 变.所以这种复用方式仅

验证当多个类之间有继承关系时,创建子类对象会导致父类初始化块的执行。

结果:当多个类之间有继承关系时,创建子类对象会导致父类初始化块的执行.