lua面向对象实现(实例化对象、继承、多态、多继承、单例模式)
lua面向对象实现:
一个类就像是一个创建对象的模具。有些面向对象语言提供了类的概念,在这些语言中每个对象都是某个特定类的实例。lua则没有类的概念,每个对象只能自定义行为和形态。不过,要在lua中模拟类也并不困难。
lua中,面向对象是用元表这个机制来实现。
首先,一般来说一个表和它的元表是不同的个体(不属于同一个表),在创建新的表时,不会自动创建元表。
setmetatable函数:设置元表
setmetatable( 表1 , 表2 ) 将表2挂接为表1的元表,并且返回经过挂接后的表1
__index字段:
元表中的__index字段,是一个非常强大的字段,它为回溯查询提供支持。而面向对象的实现基于回溯查询
当访问一个table中不存在的字段时,得到的结果为nil。但是如果这个表有元表的话,这个访问就会查找元表中的__index字段。如果没有__index字段没有赋值,那么访问结果为nil。否则,就由__index字段提供最终的结果。
__index可以赋值为一个函数,也可以是个表。是函数时,就会调用这个函数。是表的时候,就以相同的方式重新访问这个表。
注意:这里出现了三个表的个体,
我们直接操作的表,称之为表A,表A的元表称之为表B,表B的__index字段赋值的表,称之为表C
如果访问表A中的一个字段时,如果找不到,会去查看表A有没有元表B,如果有的话,就会查找B中的__index字段是否有赋值,如果赋值为表C,就会去表C中查找有没有想访问的那个字段,如果找到了,就返回那个字段,如果没有,就返回nil。
lua面向对象--对象创建
我们可以利用元表和元表__index字段来实现类对象的创建
在该类的构造函数中,定义一个新的表,然后把该类(表)设置为新定义的那个表的元表的__index字段,这样,当我们用实例的对象来调用该类的某个字段的时就会去该类中查找调用,这样就实现了对象的实例化。
例子
class.lua
local class = {}
function class:new()
local self = {} —创建新的表作为实例的对象
setmetatable( self , {__index = class}) —设置class为对象元表的__index
return self —返回该新表
end
function class:func()
print(“class : func”)
end
return class
main.lua
local class = require(“class”)
s1 = class:new() — 实例化对象s1
s1:func() ——->class : func
lua面向对象--继承
lua实现继承和实现对象实例化是一样的,利用元表和元表的__index字段来实现。
例子
class1.lua
local class1 = {}
function class1:func1()
print(“class1 : func1”)
end
class2.lua
local class2 = {}
local class1 = require(“class1”)
function class2:func2()
print(“class2 : func2”)
end
function class2:new()
setmetatable(class2 , {__index = class1}) —设置class1为class2的元表的__index字段来实 现继承
— 实例对象
local self = {}
setmetatable(self , {__index = class2})
return self
end
return class2
main.lua
local class2 = require(“class2”)
local s1 = class2:new()
s1:func1() ———>class1:func1
s1:func2() ———>class2:func2
lua面向对象--多态
lua支持多态
例子:
class1.lua
ocal class1 = {x = 0,y = 0}
function class1:new(x,y)
-- body
local self = {}
setmetatable(self,class5)
class1.__index = class1
self.x = x
self.y = y
return self
end
function class1:test()
print(self.x,self.y)
end
function class1:gto()
return 100
end
function class1:gio()
return self:gto()*2
end
return class1
class2.lua
local class2 ={}
local class2 = require("class1")
function class2:new(x,y)
setmetatable(class2, class1)
class1.__index = class2
local self = {}
setmetatable(self, class2)
class2.__index = class2
self.x = x
self.y = y
return self
end
function class2:gto()
return 50
end
return class2
main.lua
class1 = require(“class1”)
class2 = require(“class2”)
s1 = class1:new()
s2 = class2:new()
print(s1:gio()) ——->200
print(s2:gio()) ——>100
—s2对象调用基类class1的gio函数,函数内部调用class2的gto函数,实现了多态。
lua面向对象--多继承
lua中类的多继承实现也是利用的元表和元表的__index字段,不同于对象实例化和单一继承不同的是__index字段赋值的是一个函数而不是一个基类的表。
利用传入__index字段的函数来查找类中找不到的字段(函数中遍历该类继承的多个基类)
查找函数:
local function search(k,plist)
for i = 1,#plist do
local v = plist[i][k]
if v then return v end
end
—plist 为该类的基类的集合 ,k为要查找(调用继承的字段)的字段
实现继承函数:
local function createClass()
local parents = {class1,class2}
setmetatable(class3,{__index = function(t,k)
return search(k,parents)
end
这样就可以实现多继承了。
例子:
class1.lua
local class1 = {}
function class1:func1()
print("class1--func1")
end
return class1
class2.lua
local class2 ={}
function class2:func2()
print("class2:func2")
end
return class2
class3.lua
local class3 = {}
local class1 = require("class1")
local class2 = require("class2")
local function search(k,plist)
for i = 1,#plist do
local v = plist[i][k]
if v then return v end
end
local function createClass()
local parents = {class1,class2}
setmetatable(class3,{__index = function(t,k)
return search(k,parents)
end
function class3:func3()
print("class3:func3")
end
function class3:new()
local self = {}
createClass()
setmetatable(self,class3)
class3.__index = class3
return self
end
return class3
main.lua
local class3 = require("class3")
local s1 = class3:new()
s1:func1() ————->class1:func1
s1:func2() ————>class2:func2
s1:func3() ————>class3:func3
lua面向对象--单例模式
lua的单例模式是利用一个全局表来实现的
例子:
CatManager = {}
CatManager_mt = {__index = CatManager} —创建一个表做实例对象的元表,__index 设置为 这个单例类
function CatManager:new()
local self = {}
setmetatable( self , CatManager_mt) —把全局的表CatManager设置为self(新创建表)的元表的__index字段
—每次获得单例时,创建一个self表(对象),该表继承全局表CatManager,每次修改全局表中的字段后,下次再次调用时,该字段都是已经修改过的
return self
end
function CatManager:func1()
print(“func1”)
end
main.lua
require(“CatManager”)
catManager = CatManager:new()
一次导入进来后 ,整个程序都可以用,实现了单例的效果
lua面向对象实现(实例化对象、继承、多态、多继承、单例模式)的更多相关文章
- 079 01 Android 零基础入门 02 Java面向对象 01 Java面向对象基础 01 初识面向对象 04 实例化对象
079 01 Android 零基础入门 02 Java面向对象 01 Java面向对象基础 01 初识面向对象 04 实例化对象 本文知识点:实例化对象 说明:因为时间紧张,本人写博客过程中只是对知 ...
- C#面向对象(OOP)入门—第一天—多态和继承(方法重载)
面向对象是什么 面向对象是一种基于对象的编程方法,它取代了仅仅依靠方法和流程的编程方式.面向对象的编程语言中,对象(object)其实就是指特定类型.或某个类的实例.面向对象使得编程人员更容易组织和管 ...
- C#面向对象(OOP)入门—第二天—多态和继承(继承)
介绍: 第一天的内容主要是不同情形下的方法重载.这一部分则主要讲面向对象中继承的概念.首先用一个要点图形来定义继承. 继承 一个简单的例子: ClassA: class ClassA:ClassB { ...
- Lua面向对象----类、继承、多继承、单例的实现
(本文转载)学习之用,侵权立删! 原文地址 http://blog.csdn.net/y_23k_bug/article/details/19965877?utm_source=tuicool&a ...
- C++学习笔记 封装 继承 多态 重写 重载 重定义
C++ 三大特性 封装,继承,多态 封装 定义:封装就是将抽象得到的数据和行为相结合,形成一个有机的整体,也就是将数据与操作数据的源代码进行有机的结合,形成类,其中数据和函数都是类的成员,目的在于将对 ...
- C++三大特性 封装 继承 多态
C++ 三大特性 封装,继承,多态 封装 定义:封装就是将抽象得到的数据和行为相结合,形成一个有机的整体,也就是将数据与操作数据的源代码进行有机的结合,形成类,其中数据和函数都是类的成员,目的在于将对 ...
- 2019-03-27-day020-单继承与多继承
昨日回顾 类的加载顺序 类内部的代码什么时候执行? 除了方法里面的代码 其余的所有内容都是在执行这个文件的时候就从上到下依次执行的 不需要调用 如果有同名的方法.属性,总是写在后面的会生 class ...
- -1-2 java 面向对象基本概念 封装继承多态 变量 this super static 静态变量 匿名对象 值传递 初始化过程 代码块 final关键字 抽象类 接口 区别 多态 包 访问权限 内部类 匿名内部类 == 与 equal
java是纯粹的面向对象的语言 也就是万事万物皆是对象 程序是对象的集合,他们通过发送消息来相互通信 每个对象都有自己的由其他的对象所构建的存储,也就是对象可以包含对象 每个对象都有它的类型 也就是 ...
- 如何讲清楚 Java 面向对象的问题与知识?(类与对象,封装,继承,多态,接口,内部类...)
写在最前面 这个项目是从20年末就立好的 flag,经过几年的学习,回过头再去看很多知识点又有新的理解.所以趁着找实习的准备,结合以前的学习储备,创建一个主要针对应届生和初学者的 Java 开源知识项 ...
随机推荐
- 《UNIX 环境高级编程》编译环境的搭建( 运行本专栏代码必读 )
第一步:搭建基本的编译环境 安装gcc, g++, bulid-essential等编译软件 第二步:下载本书示例源码包 可在这里下载 www.apuenook.com 第三步:解压下载到的包并放在用 ...
- #ZgotmplZ go web 开发 base64 图片显示
Go Web开发,用Base64作为图片URL时遇到#ZgotmplZ的问题 - 简书 https://www.jianshu.com/p/54fc25da7c4f // var imgBase64 ...
- the ACID properties of HBase
http://hbase.apache.org/acid-semantics.html Apache HBase (TM) is not an ACID compliant database. How ...
- static 静态域 类域 静态方法 工厂方法 he use of the static keyword to create fields and methods that belong to the class, rather than to an instance of the class 非访问修饰符
总结: 1.无论一个类实例化多少对象,它的静态变量只有一份拷贝: 静态域属于类,而非由类构造的实例化的对象,所有类的实例对象共享静态域. class Employee { private static ...
- tornado安全应用之cookie
目前大多数服务器判断用户是否登录一般通过session机制,Tornado 通过 set_secure_cookie 和 get_secure_cookie 方法直接支持了这种功能.原理类似于sess ...
- 使用Primose方式解决异步编程回调的一些问题--animate动画的例子
function animate(dis, time) { var def = $.Deferred(); $('.boll') .animate({ left: dis + 'px' }, time ...
- 官方文档Core Technologies - Part 1
首先介绍系列文章内容及Spring Framework官方文档情况. 在这一系列学习中,我阅读的主要资源是5.1.2 Reference Doc.,以及论坛大神的讲解blog.另外,Spring官方也 ...
- platform_set_drvdata和platform_get_drvdata用法【转】
本文转载自:http://www.cnblogs.com/wangxianzhen/archive/2013/04/09/3009530.html 在用到Linux设备驱动的platform框架时,常 ...
- hadoop 添加,删除节点
http://www.cnblogs.com/tommyli/p/3418273.html
- PGTM通用性能测试模型
PTGM通用性能测试模型 一. 测试前期准备阶段 目标: 1. 保证系统稳定性: 2. 建立合适的测试团队. 活动: 1. 系统基础功能验证 类似于BVT测试,确保被测系统已具备进行性 ...