首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Lua中元方法的继承

在Lua中,元方法是一种特殊的函数,用于重定义表的行为。元方法可以被继承,这意味着当一个表没有定义某个元方法时,Lua会在其父表中查找该元方法。

元方法的继承是通过设置表的元表(metatable)来实现的。元表是一个普通的Lua表,其中包含了一些特殊的键,用于定义元方法。当Lua在一个表上执行某个操作时,如果该表没有定义对应的元方法,Lua会检查该表的元表是否定义了相应的元方法。如果定义了,则调用元表中的对应函数来处理该操作。

下面是一些常用的元方法及其作用:

  1. __index:用于处理表的索引操作,当访问一个表中不存在的键时被调用。可以用来实现类似于面向对象语言中的属性访问器。 示例代码:local obj = {name = "Alice"} local mt = {__index = {age = 20}} setmetatable(obj, mt) print(obj.name) -- 输出 "Alice" print(obj.age) -- 输出 20
  2. __newindex:用于处理表的新索引操作,当给一个表中不存在的键赋值时被调用。可以用来实现类似于面向对象语言中的属性赋值器。 示例代码:local obj = {} local mt = {__newindex = function(t, k, v) rawset(t, k, v * 2) end} setmetatable(obj, mt) obj.num = 10 print(obj.num) -- 输出 20
  3. add、sub、mul、div、__mod:用于处理表的加、减、乘、除、取模操作。可以用来实现表的算术运算。 示例代码:local obj1 = {value = 10} local obj2 = {value = 20} local mt = { __add = function(a, b) return a.value + b.value end, __sub = function(a, b) return a.value - b.value end, __mul = function(a, b) return a.value * b.value end, __div = function(a, b) return a.value / b.value end, __mod = function(a, b) return a.value % b.value end } setmetatable(obj1, mt) setmetatable(obj2, mt) print(obj1 + obj2) -- 输出 30 print(obj1 - obj2) -- 输出 -10 print(obj1 * obj2) -- 输出 200 print(obj1 / obj2) -- 输出 0.5 print(obj1 % obj2) -- 输出 10
  4. __call:用于处理表的函数调用操作,当一个表被当作函数调用时被调用。可以用来实现可调用的表。 示例代码:local obj = {value = 10} local mt = { __call = function(t, ...) return t.value + select(1, ...) end } setmetatable(obj, mt) print(obj(5)) -- 输出 15

元方法的继承可以通过设置元表的元表来实现多级继承。当一个表的元表没有定义某个元方法时,Lua会递归地在其元表的元表中查找,直到找到定义了该元方法的元表或到达顶级元表为止。

腾讯云相关产品和产品介绍链接地址:

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

Lua⭐️面向对象——属性、函数方法、类、继承

那怎样实现该过程呢,是通过元表功能 当调用该表时,先从该表搜索是否有key,没有再从元表修改; 当写入跟元表相同内容时,新数据时直接写到新表中去,并不会对元表造成影响,这时输出时也是输出新表内容...person={name="skode",age="99"} --对person声明新new方法 function person:new() local t={} --新表 local是为避免在外界造成不必要影响...="99"} --对person声明新new方法 function person:new(o) local t=o or {} --新表 setmetatable(t,{__index=self...-e "io.stdout:setvbuf 'no'" "newlua.lua" skode 100 >Exit code: 0 继承 person={name="skode",age="99"}...--对person声明新new方法 function person:new(o) t=o or {} --新表 setmetatable(t,{__index=self}) --为新表赋值元表

10510

Lua实现继承

原文链接:https://www.jianshu.com/p/fefe11d4544e Lua元表使用 中__index元方法可以实现面向对象和继承关系:...(Luaself) 两个类之间同样可以用__index实现继承关系: local Person = {} function Person:new(name) self....还是s(Luaself) 然后第二行打印score即s.score; 当继承关系比较复杂时,这种调用显得比较混乱且容易出问题,可以封装一个Object基类,实现继承关系链,方便方法调用且减少出问题几率...实现面向对象Object基类: 将设置__index和setmetatable操作统一写在Object类里,方便使用和减少出错,一共有两处: 实现继承关系时:在Object方法中实现继承关系(设置...要注意是,在子类调用父类方法时,尽量都是用 ClassName.super 而不要用self.super,因为luaself是不确定

3.1K20
  • lua面向对象:new,继承,多态

    概述: lua要实现类,继承,多态 BaseClass(super)为生成基类公共方法,内部开辟新以class_type为模板返回,主要为类声明服务,一个类有的__init(构造),__delete...= BaseView or BaseClass() 类继承LoginView = LoginView or BaseClass(BaseView) 通过设置class_type.New,会再返回一个新设置子类元表...再注册DeleteMe方法,依次调用子类__delete,父类__delete --保存类类型虚表 local _class = {} local lua_obj_count = 0 function...] }) -- 调用初始化方法 --如果有基类,相当于用递归,把所有基类init方法都调用了一遍,,而且是先调用最基类init,再子类init do local create...end -- 注册一个delete方法 --先调用自己__delete,再调用基类__delete obj.DeleteMe = function(self) lua_obj_count

    39220

    继承方法

    1 问题 定义一个父类,用子类去继承父类所拥有的方法、定义属性,然后使用测试文件实现子类输出父类方法信息,属性等。...2 方法 2.1 定义一个名为Person父类: 2.2 定义一个名为Student子类,并令其继承父类: 2.3 定义父类属性、方法: 2.4定义子类属性,以及输出父类属性: 2.5...Student lisi = new Student("李四",18,"165465465",54654,"四川旅游学院"); lisi.fanhui(); }} 3 结语 针对于继承类以及类中方法和属性...,首先应该创建父类和子类继承,然后是定义类属性和方法,最后输出返回它内容。...单单从目前来继承类属于比较基础方法,之后还会在此基础上实现更多延伸,例如分块利用,比所有代码写在一起更加方便,整洁。

    17010

    python比较列表中元素大小和列表中元判定

    列表判定主要是判定列表中是否包含某个元素,使用逻辑运算符判定就可以了;列表比较稍微复杂一些,首先比较是两个列表中对应元素大小,如果元素值一样,再比较列表长度。...'php', 'MySql', 'C++', 'C', 'php', 'C#'] print('MySql' in list1) print('MySql' not in list1) 二、列表之间大小比较...list3 = [2, 3, 4] list4 = [2, 3] print(list2 > list4) # 优先比较元素大小print(list3 > list4) 以上是对Python列表元素判定与比较简单文字讲解...,详细讲解视频课程在python自学网上,这是视频地址(http://www.wakey.com.cn/video-list-base.html),感兴趣同学可以去瞅一瞅,说不定就有收获呢~

    5.7K20

    Lua元表和元方法

    库定义相关方法 到目前为止,我们见过所有元方法针对都是核心Lua语言。Lua语言虚拟机会检测一个操作中设计值是否有存在对应元方法元表。...所有的这些参数都有默认值,因此我们希望在创建窗口对象时只需要给出那些不同于默认值参数即可。第一种方法是使用一个构造器来填充不存在字段,第二种方法是让新窗口从一个原型窗口继承所有不存在字段。...因此,Lua语言会以w(表)和"width"(不存在键)为参数来调用这个元方法。元方法随后会用这个键来检索原型并返回结果。 在Lua语言中,使用元方法index来实现继承是很普通方法。...因此,Lua语言就会在这个表中继续查找,即等价地执行prototype[“width”],并得到预期结果。 将一个表用作index元方法为实现单继承提供了一种简单快捷方法。...组合使用元方法index和__newindex可以实现Lua语言中一些强大结构,例如只读表、具有默认值表和面向对象编程中继承。 具有默认值表 一个普通表中所有字段默认值都是nil。

    64640

    Lua序列化方法

    lua序列化实现使用是string.dump (),关于string.dump ()介绍,luaAPI文档中写到 string.dump (function [, strip]) 返回一个包含给定函数二进制表示...(二进制块)字符串,以便稍后对该字符串加载将返回函数一个副本(但带有新upvalues)。...,load序列化之后函数调用中,debug照样能打印出来, 举个例子 序列化 使用IO读取一个lua文件存入变量data,然后序列化loadstring之后函数,伪代码如下: dumpData=...,再使用loadstring或load方法反序列化成函数(这个我是这么理解),伪代码如下: data=io.open(path,“rb”):read("*a") dumpfunc=loadstring...(data) 实际代码演示: 要序列化文件如下 --[[ ModuleName : dumpfile.lua Path : E:\SluaNetProtol\src\test\dumpfile.lua

    1.7K20

    JS 继承多种方法

    一、原型链 学过java同学应该都知道,继承是java重要特点之一,许多面向对象语言都支持两种继承方式:接口继承和实现继承,接口继承继承方法签名,而实现继承继承实际方法,在js中,由于函数没有签名...原型链继承 最常见继承方法就是使用原型链实现继承啦,也就是我们上面所介绍,接下来,还是看一个实际例子。...组合继承 组合继承主要是将原型链和借用构造函数技术组合到一块,从而发货两者之长一种继承模式,主要是使用原型链实现对原型属性和方法基础,通过借用构造函数实现对实例属性基础,这样,可以通过在原型上定义方法实现函数复用...,融合了它们优点,现在已经成为js中最常用继承方法。...寄生式继承 寄生式继承其实和我们前面说创建对象方法寄生构造函数和工程模式很像,创建一个仅用于封装继承过程函数,该函数在内部以某种方法来增强对象,最后再返回该对象。

    2.8K10

    Java继承概念及方法

    继承就是子类继承父类特征和行为,使得子类对象(实例)具有父类实例域和方法,或子类从父类继承方法,使得子类具有父类相同行为。...(复用性主要是可以多次使用,不用再多次写同样代码)继承之后代码: 企鹅类: 老鼠类: 继承特性 子类拥有父类非private属性,方法。...子类从它父类中继承可访问数据域和方法,也可以添加新数据域和新方法。...不能在子类中使用父类构造方法名来调用父类构造方法。 父类构造方法不被子类继承。...静态方法中不能使用 super 关键字。 调用父类方法语法: super.方法名(参数列表); 如果是继承方法,是没有必要使用 super 来调用,直接即可调用。

    44020

    Lua元表和元方法

    Lua中每个值都可具有元表。 元表是普通Lua表,定义了原始值在某些特定操作下行为。你可通过在值原表中设置特定字段来改变作用于该值操作某些行为特征。...例如,当数字值作为加法操作数时,Lua检查其元表中"__add"字段是否有个函数。如果有,Lua调用它执行加法。 我们称元表中键为事件(event),称值为元方法(metamethod)。...当Lua对某值执行其中一个操作时,检查该值是否含有元表以及相应事件。如果有,与该键关联值(元方法)控制Lua如何完成操作。 元表控制后面列举操作。每个操作由相应名字标识。...函数getcomphandler定义Lua如何选择比较操作符方法。只有待比较两个对象类型和选定操作对应方法都相同,才会选择该元方法。...注意,假定a <= b等价于not (b < a),那么当没有“le”元方法时,Lua尝试“lt”。 "index": 索引访问table[key]。

    1.7K30

    获取页面中被选中元 JS原生方法 与 jQuery方法 分析

    说明 测试用浏览器是chrome,jquery版本用了1.11.3和3.2.0 js 原生方法 方法一: document.getElementById(elementID)["checked"]...或者 null,但是这个方法来获取checked属性值,并不好用,他有和方法三 一样缺陷,他始终都只会获取checked属性初始值,用户在页面上点击是不会改变他!...方法二 is() 方法用于查看选择元素是否匹配选择器,:checked 是jQuery中选择器 选取所有被选中元素(复选框或单选按钮)这个方法是推荐使用jQuery方法 方法三 这个方法不推荐使用...,缺陷和上面js方法中提到缺陷是一样 方法四 这个方法非常推荐使用 prop() 方法设置或返回被选元素属性和值。...[ name ] 这里我们可以理解为document.getElementById(elem)[name] = value,也就是上面说js原生方法一 总结 获取页面被选中元方法有很多,

    5.3K20

    Python中元概念

    动态修改类:可以动态地添加、修改或删除类属性和方法。 检查类合法性:可以在类定义阶段进行一些检查,避免错误定义。...在Python中,我们通常使用抽象基类(Abstract Base Class)来实现接口功能。抽象基类是一种特殊类,它不能被实例化,只能被继承。...通过继承抽象基类,子类必须实现父类定义一组方法,否则会引发异常。...当我们尝试创建一个未实现area()方法子类Square时,会引发TypeError异常,提示我们必须实现该方法。...接口数量:Java类可以实现多个接口,而Python类只能继承一个元类。这是因为Python继承树是单继承,而Java继承树是多继承

    18300

    OpenRestyNginx Lua服务远程调试方法

    很多Nginx Lua程序员入门过程中会遇到一个问题就是选择编辑器IDE,其实Lua编辑器IDE过去流行也有几种,但大多数都被人遗忘了,如果只是做纯Lua代码语法检查,代码补全,很多IDE都可以做到...而可以在线调试Nginx程序,设置断点可视化IDE,那应该ZeroBraneStudio这个编辑器,低层利用Lua Socket进行通信,可以可视化在IDE中,某句Lua代码,比如ngx.say("...https://lua.ren")上设置断点,然后Nginx程序执行到此地会停下,在IDEOutput窗口有对应字样输出。...经过了将近5年左右时间,国内用ZeroBraneStudio的人就更少应该,而且多数情况,调试服务找问题,不是下断点分析内存等相关资源,设断点这种方法效率不是很高。...更高级方法是春哥做法,直接用火焰图可视化Lua执行过程,用 Xray可视化跟踪OpenResty服务,用 Ylang辅助产生新功能,进行综合各种指标数据分析,那就进入了另外一种全新视角。

    5.4K20

    继承四种方法

    继承 原型链方法 继承了过多没用属性 通过使用new关键字来实现继承父元素属性和方法,再通过prototype属性来改变函数原型,从而实现一条完整原型链,从而实现子函数可以继承父函数属性和方法 function...fathername 借用构造函数 不能继承构造函数原型 // 1....; } // 2 .子构造函数 function Son(uname, age, score) { // this 指向子构造函数对象实例 // 3.使用call方式实现子继承属性...F做中间层,让F和Father共有原型,也就是把Father原型赋值给F一份,在F和son之间操作,这样就可以隔开son和father但又不影响继承 function inherit(Target,Origin...;//通过new方法把F原型返回给目标 } Father.prototype.lastName = 'lin'; function Father() {} function Son() {} inherit

    33040

    继承构造方法内存处理

    1、继承关系内存解释 实际上在面向对象第一天讲解当中,我们对内存方面做了一些隐瞒。因为除了Object类,所有的类都是有父类。...Person(String name,int age) { this.name = name; this.age = age; } //get/set方法...对外表现就”像个父类对象一样”。 仅仅在调用方法时,会调用子类重写后方法。...Person p=new Chinese(); 2.2、向下转型 当出现多态后,父类Person引用指向子类对象,当强转为子类引用时,由于堆内存当中存储仍为子类对象,包含子类一切成员。...但是,如果没有出现多态,仅仅创建父类对象(如果父类不是抽象类的话),则为父类Person引用指向Person对象,没有子类对象。

    47010
    领券