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 开源知识项 ...
随机推荐
- Selenium学习(二)入门小例子
1)打开百度页面 2)输入“hello” 3)点击百度一下按钮 from selenium import webdriver url = "http://" + "www ...
- JavaScript读书笔记(4)-变量、作用域和内存问题
1.ECMAScript数据类型分为:基本类型值和引用类型值: ECMAScript中所有函数的参数都是按值传递的: 检查对象的类型:varible instanceof constructor Al ...
- 简述C++中的多态机制
前言 封装性,继承性,多态性是面向对象语言的三大特性.其中封装,继承好理解,而多态的概念让许多初学者感到困惑.本文将讲述C++中多态的概念以及多态的实现机制. 什么是多态? 多态就是多种形态,就是许多 ...
- 主题:iframe高度的自适应
在项目开发中,遇到的一个问题.弹出的页面中有iframe.例 <iframe src="www.baidu.html" width="100%" char ...
- hdu5698 百度之星2016round2b第3题
这题首先是找规律推公式,然后就是组合数学的知识了. 题目是问到第n行第m列的格式有几种方案,我们可以用手算的方法列出当n和m比较小时的所有答案 比如我列出以下8*8的矩阵 矩阵上的数表示从那个位置到最 ...
- mongoose在Windows Server 2003上不能访问问题的解决
这两天在部署EasyDarwin开源流媒体服务器到Windows Server 2003的时候,奇怪地发现,在Windows 2003上面,mongoose的web管理端口居然无法访问,但通过nets ...
- Netty 100万级高并发服务器配置
前言 每一种该语言在某些极限情况下的表现一般都不太一样,那么我常用的Java语言,在达到100万个并发连接情况下,会怎么样呢,有些好奇,更有些期盼. 这次使用经常使用的顺手的netty NIO框架(n ...
- SPDY: An experimental protocol for a faster web HTTP/2
http://www.chromium.org/spdy/spdy-whitepaper https://en.wikipedia.org/wiki/SPDY Internet protocol su ...
- android studio发布公共类库到服务器maven仓库
在上一篇中提到了怎么创建私有maven库,这篇主要结合android studio的使用,直接进入正题,看以下步骤 1.创建android项目 创建Project,然后加一个library的modul ...
- ZOJ - 3954 Seven-Segment Display 【状态标记】
题目链接 http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3954 题意 有一块 LED 灯 然后上面有七块灯管 在显示不同数 ...