浅谈Lua的面向对象特性

面向对象的特性

  • 类: 类是可扩展的模板用来创建对象,提供状态的初始值(成员变量)和行为的实现。
  • 对象: 它是类的实例并具有分配给自己独立的内存。
  • 继承: 它是由变量和类的函数被其他类继承的概念。
  • 封装: 它是将数据和函数相结合的一类内的方法。数据可以在类的外部与函数的帮助下进行访问。它也被称为数据抽象。

Lua的OOP

在Lua中实现面向对象与表和Lua的第一类函数。通过将函数和相关数据插入表中形成一个对象。继承可以在metatables的帮助下来实现,提供了一个查找机制不存在的函数(方法)和在父对象字段。

在Lua表有这样的状态和标识对象,它是独立于值的特性。两个对象(表),具有相同的值但在不同的对象,而一个对象可以具有在不同的值,但它始终是相同的对象。就像对象表中有一个生命周期,独立创建或被创建。
一个真实世界的例子

面向对象的概念是广泛的,但要明白和获取最大利益。

让我们考虑一个简单的数学例子。我们经常会遇到,我们工作在不同的形状像圆形,长方形和正方形的情况。

形状可以有一个共同的属性区。因此,我们可以从与共同属性区域的基础对象形状扩展的其它形状。每个形状都可以有其自己的性质和功能类似的矩形可以有属性的长度,宽度,面积作为其属性,printArea中和calculateArea作为它的函数。
创建一个简单的类

一个简单的类实现矩形三个属性面积,长度和宽度如下所示。它也有一个printArea中功能打印所计算的面积。

代码如下:

-- Meta class
Rectangle = {area = 0, length = 0, breadth = 0}

-- Derived class method new
function Rectangle:new (o,length,breadth)
  o = o or {}
  setmetatable(o, self)
  self.__index = self
  self.length = length or 0
  self.breadth = breadth or 0
  self.area = length*breadth;
  return o
end

-- Derived class method printArea
function Rectangle:printArea ()
  print("The area of Rectangle is ",self.area)
end

创建对象

创建对象是类的实例分配存储器的过程。每个对象具有它自己的存储器和共享公用类数据。

代码如下:

r = Rectangle:new(nil,10,20)

访问属性

在类中用点 . 操作符,如下图所示,可以访问属性

代码如下:

print(r.length)

访问成员函数

使用冒号运算符,如下图所示,可以访问对象成员函数。

代码如下:

r:printArea()

存储器被分配和初始值被设定。初始化过程可以比在其它面向对象的语言构造。它只是一项功能设定值,如上图所示。
完整例子

让我们来看看使用面向对象的Lua中一个完整的例子。

代码如下:

-- Meta class
Shape = {area = 0}

-- Base class method new
function Shape:new (o,side)
  o = o or {}
  setmetatable(o, self)
  self.__index = self
  side = side or 0
  self.area = side*side;
  return o
end

-- Base class method printArea
function Shape:printArea ()
  print("The area is ",self.area)
end

-- Creating an object
myshape = Shape:new(nil,10)

myshape:printArea()

当运行上面的程序,会得到如下的输出。

代码如下:

The area is  100

Lua的继承

继承是扩展形状简单的基本对象,以矩形,正方形等的处理。它通常用于在真实世界中的共享和扩展的基本性质和功能。

让我们看一个简单的类扩展。有一个类,如下图所示。

代码如下:

-- Meta class
Shape = {area = 0}
-- Base class method new
function Shape:new (o,side)
  o = o or {}
  setmetatable(o, self)
  self.__index = self
  side = side or 0
  self.area = side*side;
  return o
end
-- Base class method printArea
function Shape:printArea ()
  print("The area is ",self.area)
end

我们可以扩展的形状为正方形类如下所示。

代码如下:

Square = Shape:new()
-- Derived class method new
function Square:new (o,side)
  o = o or Shape:new(o,side)
  setmetatable(o, self)
  self.__index = self
  return o
end

重载基础函数

我们可以重载基类函数使用基类中的函数,而不是派生类它自己再实现,如下图所示

代码如下:

-- Derived class method printArea
function Square:printArea ()
  print("The area of square is ",self.area)
end

继承完整的例子

Lua中我们可以扩展的简单类实现,如上图所示metatables另一个新的方法。所有的成员变量和基类的函数被保留在派生类。

代码如下:

-- Meta class
Shape = {area = 0}
-- Base class method new
function Shape:new (o,side)
  o = o or {}
  setmetatable(o, self)
  self.__index = self
  side = side or 0
  self.area = side*side;
  return o
end
-- Base class method printArea
function Shape:printArea ()
  print("The area is ",self.area)
end

-- Creating an object
myshape = Shape:new(nil,10)
myshape:printArea()

Square = Shape:new()
-- Derived class method new
function Square:new (o,side)
  o = o or Shape:new(o,side)
  setmetatable(o, self)
  self.__index = self
  return o
end

-- Derived class method printArea
function Square:printArea ()
  print("The area of square is ",self.area)
end

-- Creating an object
mysquare = Square:new(nil,10)
mysquare:printArea()

Rectangle = Shape:new()
-- Derived class method new
function Rectangle:new (o,length,breadth)
  o = o or Shape:new(o)
  setmetatable(o, self)
  self.__index = self
  self.area = length * breadth
  return o
end

-- Derived class method printArea
function Rectangle:printArea ()
  print("The area of Rectangle is ",self.area)
end

-- Creating an object
myrectangle = Rectangle:new(nil,10,20)
myrectangle:printArea()

当我们运行上面的程序,会得到下面的输出。

代码如下:

The area is  100
The area of square is  100
The area of Rectangle is  200

在上面的例子中,我们创建了两个派生类Rectangle和Square从基类Square。因此能够在此改变基类的功能的派生类。在本实现例子中,派生类会取代函数printArea。

(0)

相关推荐

  • Lua面向对象之多重继承、私密性详解

    在Lua中的多重继承和私密性可能用得比较少,也可能只是我个人用得比较少. 本来想偷懒不写这文章的,因为我今天刚买了个漂移板,连起步都还没学会啊,想多学一会. 咳咳,本着坚持不懈.负责到底的态度,我还是决定随便写几句~(小若:随便写几句是几吨意思啊?!) 1.多重继承之在多个类中查找一个字段 我发现这些高(shen)智(jing)商(bing)人群真的很厉害,这种技巧都能想到,很佩服. 其实多重继承没什么特别的,除非两个将要被继承的类有相同的函数名和属性,否则,处理起来很简单.   无非就是在多个

  • Lua 极简入门指南(七):面向对象编程

    类 在很多面向对象的语言中有类(class)的概念,对象是类的实例.Lua 中不存在类的概念.Lua 就像 JavaScript 一样是面向原型的语言(http://en.wikipedia.org/wiki/Prototype-based_programming),这类语言使用一个对象表示一个"类",其他对象(此类的实例)使用此对象作为原型.我们有两个 table p 和 obj,将 p 设置为 obj 的原型(回顾:http://www.jb51.net/article/56690

  • Lua中的面向对象编程详解

    简单说说Lua中的面向对象 Lua中的table就是一种对象,看以下一段简单的代码: 复制代码 代码如下: local tb1 = {a = 1, b = 2} local tb2 = {a = 1, b = 2} local tb3 = tb1   if tb1 == tb2 then      print("tb1 == tb2") else      print("tb1 ~= tb2") end   tb3.a = 3 print(tb1.a) 上述代码会输

  • 浅谈Lua的面向对象特性

    面向对象的特性 类: 类是可扩展的模板用来创建对象,提供状态的初始值(成员变量)和行为的实现. 对象: 它是类的实例并具有分配给自己独立的内存. 继承: 它是由变量和类的函数被其他类继承的概念. 封装: 它是将数据和函数相结合的一类内的方法.数据可以在类的外部与函数的帮助下进行访问.它也被称为数据抽象. Lua的OOP 在Lua中实现面向对象与表和Lua的第一类函数.通过将函数和相关数据插入表中形成一个对象.继承可以在metatables的帮助下来实现,提供了一个查找机制不存在的函数(方法)和在

  • 浅谈Java实现面向对象编程java oop

    一.对象的综述 面向对象编程(OOP)具有多方面的吸引力.对管理人员,它实现了更快和更廉价的开发与维护过程.对分析与设计人员,建模处理变得更加简单,能生成清晰.易于维护的设计方案.对程序员,对象模型显得如此高雅和浅显.此外,面向对象工具以及库的巨大威力使编程成为一项更使人愉悦的任务.每个人都可从中获益,至少表面如此. 所有编程语言的最终目的都是解决企业又或者人在现实生活中所遇到的问题,最初我们的程序可能长这样"11111100001",相信大家都不会陌生,只是大家没这么子去敲过代码.再

  • 浅谈JavaScript中面向对象的的深拷贝和浅拷贝

    理解深拷贝和浅拷贝之前需要弄懂一些基础概念,内存中存储的变量类型分为值类型和引用类型. 1.值类型赋值的存储特点, 将变量内的数据全部拷贝一份, 存储给新的变量. 例如:var num = 123 :var num1=num; 表示变量中存储的数字是 123.然后将数据拷贝一份,就是将 123 拷贝一份. 那么内存中有 2 个 数组;将拷贝数据赋值给 num2,其特点是在内存中有两个数据副本.这可以理解为浅拷贝. 2.引用类型的赋值. var o={name:'张三'}: var obj=o;

  • 浅谈数据库事务四大特性

    数据库四大特性分别是:原子性.一致性.分离性.持久性.下面我们看看具体介绍. 原子性 事务的原子性指的是,事务中包含的程序作为数据库的逻辑工作单位,它所做的对数据修改操作要么全部执行,要么完全不执行.这种特性称为原子性. 事务的原子性要求,如果把一个事务可看作是一个程序,它要么完整的被执行,要么完全不执行.就是说事务的操纵序列或者完全应用到数据库或者完全不影响数据库.这种特性称为原子性. 假如用户在一个事务内完成了对数据库的更新,这时所有的更新对外部世界必须是可见的,或者完全没有更新.前者称事务

  • 浅谈JavaScript中面向对象技术的模拟

    一.引言 在C#和Java语言中,面向对象是以类的方式实现的,特别是继承这个特性,类的方式继承表现出了强大的功能,而且也易于学习.JavaScript不是纯的面向对象的语言,而是基于对象的语言,对象的继承是以原型函数的形式继承的,很多初学者刚开始接触的时候不太理解,但是JavaScript这种以原型函数的形式实现面向对象技术,不仅是可行的,而且还为面向对象技术提供了动态继承的功能,本文主要讨论了JavaScript的面向对象技术. 二.原型对象概述 每个JavaScript对象都有原型对象,对象

  • 浅谈对c# 面向对象的理解

    一.了解面向对象 1.概念基本理解:1).一个个体可以看做是一个对象,例如:人这个个体: 2).有共同属性的一类作为一个个体,例如:学生.白领.农民工: 3).结构体是用户自定义的数据类型,可以定义不同数据类型的变量,结构体也是面向对象的核心: 2.基本特性: 1)封装:是隐藏信息的特性,具有"封装"意识,是掌握面向对象分析与设计技巧的关键. 最简单的理解:创建一个对象的整体,使对象的属性可以具有赋值.取值的功能,也就是对象中的变量可以赋值.取值.,是一种认为的抽象出来的对象的概念.

  • 浅谈JavaScript实现面向对象中的类

    对象,是人们要进行研究的任何事物,从最简单的整数到复杂的飞机等均可看作对象,它不仅能表示具体的事物,还能表示抽象的规则.计划或事件.--引自百度百科 面向对象编程,是当前最流行的编程模式.但令人沮丧的是,作为前端应用最为广泛的javascript,并不支持面向对象. javascript没有访问控制符,它没有定义类的关键字class,它没有支持继承的extend或冒号,它也没有用 来支持虚函数的virtual,不过,Javascript是一门灵活的语言,下面我们就看看没有关键字class的Jav

  • 浅谈Lua语句

    Lua 中的语句支持赋值,控制结构,函数调用,还有变量声明. 不允许空的语句段,因此 ;; 是非法的. 1 语句组 | chuncks 复制代码 代码如下: chunck ::= {stat[';']} ([';'] 应该是表示语句组后面 ; 是可选项.) 2 语句块 | blocks 复制代码 代码如下: block ::= chunck stat ::= do block end 可以将一个语句块显式地写成语句组,可以用于控制局部变量的作用范围. 3 赋值 | assignment Lua

  • 浅谈mysql8.0新特性的坑和解决办法(小结)

    一.创建用户和授权 在mysql8.0创建用户和授权和之前不太一样了,其实严格上来讲,也不能说是不一样,只能说是更严格,mysql8.0需要先创建用户和设置密码,然后才能授权. #先创建一个用户 create user 'hong'@'%' identified by '123123'; #再进行授权 grant all privileges on *.* to 'hong'@'%' with grant option; 如果还是用原来5.7的那种方式,会报错误: grant all privi

  • 浅谈PostgreSQL 11 新特性之默认分区

    文章目录 PosgtreSQL 11 支持为分区表创建一个默认(DEFAULT)的分区,用于存储无法匹配其他任何分区的数据.显然,只有 RANGE 分区表和 LIST 分区表需要默认分区. CREATE TABLE measurement ( city_id int not null, logdate date not null, peaktemp int, unitsales int ) PARTITION BY RANGE (logdate); CREATE TABLE measuremen

随机推荐