加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

LUA 面向对象

发布时间:2020-12-14 22:21:07 所属栏目:大数据 来源:网络整理
导读:类继承的实现方式有三种类式继承、原型继承、掺元继承。 lua是采用类式继承。 1. PIL中的例子 http://book.luaer.cn/_98.htm 2.云风的例子 http://blog.codingnow.com/2006/06/oo_lua.html 定义类的函数 -类的vtbl(除ctor super new外,这3个是定义在 类.xx

类继承的实现方式有三种类式继承、原型继承、掺元继承。

lua是采用类式继承。

1. PIL中的例子 http://book.luaer.cn/_98.htm


2.云风的例子 http://blog.codingnow.com/2006/06/oo_lua.html

定义类的函数 ->类的vtbl(除ctor super new外,这3个是定义在 类.xxx 中,而不是 vtbl.xxx中 )

访问对象的函数以及静态成员变量->obj.xxx->_class[class_type]->自己类的vtbl

???????????????????????????????? ->找不到->_class[super]->super类的vtbl

???????????????????????????????? ->....找到了后加入自己类的vtbl中,下次不用再找


定义对象的成员变量是定义到obj.xxx中的。


还有不能定义和访问类的静态变量,因为被__newindex劫持到vbtl了,再给它加__index吧。

setmetatable
	(
		class_type,{	__newindex=
			function(t,k,v)
				vtbl[k]=v
			end,__index =
			function(t,k)
				return vtbl[k]
			end
		}
	)
又因为 vbtl会把访问过的super的静态函数和变量加入,导致和c++不同的一点是部分访问过的、子类无定义的、静态变量函数,被继承了。
	if super then
		setmetatable(vtbl,{__index=
			function(t,k)
				local ret=_class[super][k]
				vtbl[k]=ret
				return ret
			end
		})
	end




类的静态变量定义到类(类对象,非对象)中。非静态的在可以在ctor中,用self.xxx的方式初始化。

AA = class(BB)

AA.TYPE = "humen" --静态变量

--------以下列出所有成员变量

-- hp

-- mp

-- friend

function AA.ctor()

        --需要初始化的成员变量,不需要初始化的放着任它nil不用管

        self.friend = new friend

end





3.middleclasshttps://github.com/kikito/middleclass/wiki?? 来自http://love2d.org/wiki/Libraries

-- middleclass.lua - v2.0 (2011-09)
-- Copyright (c) 2011 Enrique Garc铆a Cota
-- Permission is hereby granted,free of charge,to any person obtaining a copy of this software and associated documentation files (the "Software"),to deal in the Software without restriction,including without limitation the rights to use,copy,modify,merge,publish,distribute,sublicense,and/or sell copies of the Software,and to permit persons to whom the Software is furnished to do so,subject to the following conditions:
-- The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-- THE SOFTWARE IS PROVIDED "AS IS",WITHOUT WARRANTY OF ANY KIND,EXPRESS OR IMPLIED,INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,DAMAGES OR OTHER LIABILITY,WHETHER IN AN ACTION OF CONTRACT,TORT OR OTHERWISE,ARISING FROM,OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-- Based on YaciCode,from Julien Patte and LuaObject,from Sebastien Rocca-Serra

local _classes = setmetatable({},{__mode = "k"})

local function _setClassDictionariesMetatables(klass)
  local dict = klass.__instanceDict
  dict.__index = dict

  local super = klass.super
  if super then
    local superStatic = super.static
    setmetatable(dict,super.__instanceDict)
    setmetatable(klass.static,{ __index = function(_,k) return dict[k] or superStatic[k] end })
  else
    setmetatable(klass.static,k) return dict[k] end })
  end
end

local function _setClassMetatable(klass)
  setmetatable(klass,{
    __tostring = function() return "class " .. klass.name end,__index    = klass.static,__newindex = klass.__instanceDict,__call     = function(self,...) return self:new(...) end
  })
end

local function _createClass(name,super)
  local klass = { name = name,super = super,static = {},__mixins = {},__instanceDict={} }
  klass.subclasses = setmetatable({},{__mode = "k"})

  _setClassDictionariesMetatables(klass)
  _setClassMetatable(klass)
  _classes[klass] = true

  return klass
end

local function _createLookupMetamethod(klass,name)
  return function(...)
    local method = klass.super[name]
    assert( type(method)=='function',tostring(klass) .. " doesn't implement metamethod '" .. name .. "'" )
    return method(...)
  end
end

local function _setClassMetamethods(klass)
  for _,m in ipairs(klass.__metamethods) do
    klass[m]= _createLookupMetamethod(klass,m)
  end
end

local function _setDefaultInitializeMethod(klass,super)
  klass.initialize = function(instance,...)
    return super.initialize(instance,...)
  end
end

local function _includeMixin(klass,mixin)
  assert(type(mixin)=='table',"mixin must be a table")
  for name,method in pairs(mixin) do
    if name ~= "included" and name ~= "static" then klass[name] = method end
  end
  if mixin.static then
    for name,method in pairs(mixin.static) do
      klass.static[name] = method
    end
  end
  if type(mixin.included)=="function" then mixin:included(klass) end
  klass.__mixins[mixin] = true
end

Object = _createClass("Object",nil)

Object.static.__metamethods = { '__add','__call','__concat','__div','__le','__lt','__mod','__mul','__pow','__sub','__tostring','__unm' }

function Object.static:allocate()
  assert(_classes[self],"Make sure that you are using 'Class:allocate' instead of 'Class.allocate'")
  return setmetatable({ class = self },self.__instanceDict)
end

function Object.static:new(...)
  local instance = self:allocate()
  instance:initialize(...)
  return instance
end

function Object.static:subclass(name)
  assert(_classes[self],"Make sure that you are using 'Class:subclass' instead of 'Class.subclass'")
  assert(type(name) == "string","You must provide a name(string) for your class")

  local subclass = _createClass(name,self)
  _setClassMetamethods(subclass)
  _setDefaultInitializeMethod(subclass,self)
  self.subclasses[subclass] = true
  self:subclassed(subclass)

  return subclass
end

function Object.static:subclassed(other) end

function Object.static:include( ... )
  assert(_classes[self],"Make sure you that you are using 'Class:include' instead of 'Class.include'")
  for _,mixin in ipairs({...}) do _includeMixin(self,mixin) end
  return self
end

function Object:initialize() end

function Object:__tostring() return "instance of " .. tostring(self.class) end

function class(name,super,...)
  super = super or Object
  return super:subclass(name,...)
end

function instanceOf(aClass,obj)
  if not _classes[aClass] or type(obj) ~= 'table' or not _classes[obj.class] then return false end
  if obj.class == aClass then return true end
  return subclassOf(aClass,obj.class)
end

function subclassOf(other,aClass)
  if not _classes[aClass] or not _classes[other] or aClass.super == nil then return false end
  return aClass.super == other or subclassOf(other,aClass.super)
end

function includes(mixin,aClass)
  if not _classes[aClass] then return false end
  if aClass.__mixins[mixin] then return true end
  return includes(mixin,aClass.super)
end
使用方法:
require 'middleclass'

Person = class('Person') --this is the same as class('Person',Object) or Object:subclass('Person')
function Person:initialize(name)
  self.name = name
end
function Person:speak()
  print('Hi,I am ' .. self.name ..'.')
end

AgedPerson = class('AgedPerson',Person) -- or Person:subclass('AgedPerson')
AgedPerson.static.ADULT_AGE = 18 --this is a class variable
function AgedPerson:initialize(name,age)
  Person.initialize(self,name) -- this calls the parent's constructor (Person.initialize) on self
  self.age = age
end
function AgedPerson:speak()
  Person.speak(self) -- prints "Hi,I am xx."
  if(self.age < AgedPerson.ADULT_AGE) then --accessing a class variable from an instance method
    print('I am underaged.')
  else
    print('I am an adult.')
  end
end

local p1 = AgedPerson:new('Billy the Kid',13) -- this is equivalent to AgedPerson('Billy the Kid',13) - the :new part is implicit
local p2 = AgedPerson:new('Luke Skywalker',21)
p1:speak()
p2:speak()
Person.speak(self)可以看出,也是没super的,要显式指明父类。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读