logo

第六章:面向对象编程

作者
Modified on
Reading time
3 分钟阅读:..评论:..

Lua 本身不是一个面向对象的语言,但它提供了强大而灵活的机制来实现面向对象编程(OOP)的概念。本章将探讨如何在 Lua 中实现类、对象、继承和多态等 OOP 特性。

6.1 使用表实现类

在 Lua 中,我们使用表和函数来模拟类和对象。

基本类的实现

local Dog = {} Dog.__index = Dog function Dog.new(name) local self = setmetatable({}, Dog) self.name = name return self end function Dog:bark() print(self.name .. " says: Woof!") end -- 使用类 local myDog = Dog.new("Buddy") myDog:bark() -- 输出: Buddy says: Woof!

6.2 方法和self参数

在 Lua 中,self 是一个隐含的参数,代表调用方法的对象实例。

使用冒号语法

function Dog:eat(food) print(self.name .. " is eating " .. food) end myDog:eat("kibble") -- 输出: Buddy is eating kibble

冒号语法 : 自动将调用对象作为第一个参数(self)传递给方法。

6.3 继承的实现

Lua 使用元表来实现继承。

local Animal = {} Animal.__index = Animal function Animal.new(name) local self = setmetatable({}, Animal) self.name = name return self end function Animal:speak() print(self.name .. " makes a sound") end -- Cat 继承自 Animal local Cat = setmetatable({}, {__index = Animal}) Cat.__index = Cat function Cat.new(name) local self = setmetatable(Animal.new(name), Cat) return self end function Cat:speak() print(self.name .. " meows") end -- 使用 local myCat = Cat.new("Whiskers") myCat:speak() -- 输出: Whiskers meows

6.4 多态

多态允许不同类的对象对同一消息做出响应。

local function makeSound(animal) animal:speak() end local myDog = Dog.new("Rex") local myCat = Cat.new("Fluffy") makeSound(myDog) -- 输出: Rex says: Woof! makeSound(myCat) -- 输出: Fluffy meows

6.5 私有成员的模拟

Lua 没有内置的私有成员机制,但我们可以使用闭包来模拟。

function Dog.new(name) local age = 0 -- 私有变量 local self = setmetatable({}, Dog) self.name = name function self:getAge() return age end function self:haveBirthday() age = age + 1 end return self end local myDog = Dog.new("Spot") myDog:haveBirthday() print(myDog:getAge()) -- 输出: 1 print(myDog.age) -- 输出: nil

6.6 元方法和运算符重载

元方法允许自定义表的行为,包括运算符重载。

local Vector = {} Vector.__index = Vector function Vector.new(x, y) return setmetatable({x = x, y = y}, Vector) end function Vector:__add(other) return Vector.new(self.x + other.x, self.y + other.y) end function Vector:__tostring() return "(" .. self.x .. ", " .. self.y .. ")" end local v1 = Vector.new(1, 2) local v2 = Vector.new(3, 4) local v3 = v1 + v2 print(v3) -- 输出: (4, 6)

6.7 面向对象设计模式

单例模式

local Singleton = {} function Singleton.getInstance() if not Singleton.instance then Singleton.instance = { data = 0, incrementData = function(self) self.data = self.data + 1 end } end return Singleton.instance end local s1 = Singleton.getInstance() local s2 = Singleton.getInstance() s1:incrementData() print(s2.data) -- 输出: 1

工厂模式

local ShapeFactory = {} function ShapeFactory.createShape(shapeType) if shapeType == "circle" then return { draw = function() print("Drawing a circle") end } elseif shapeType == "square" then return { draw = function() print("Drawing a square") end } else error("Unsupported shape type") end end local circle = ShapeFactory.createShape("circle") circle.draw() -- 输出: Drawing a circle

6.8 实践项目:简单的图形库

让我们创建一个简单的图形库来演示面向对象编程的概念。

-- Shape 基类 local Shape = {} Shape.__index = Shape function Shape.new() return setmetatable({}, Shape) end function Shape:draw() error("Draw method must be implemented by subclasses") end -- Circle 类 local Circle = setmetatable({}, {__index = Shape}) Circle.__index = Circle function Circle.new(radius) local self = setmetatable(Shape.new(), Circle) self.radius = radius return self end function Circle:draw() print("Drawing a circle with radius " .. self.radius) end -- Rectangle 类 local Rectangle = setmetatable({}, {__index = Shape}) Rectangle.__index = Rectangle function Rectangle.new(width, height) local self = setmetatable(Shape.new(), Rectangle) self.width = width self.height = height return self end function Rectangle:draw() print("Drawing a rectangle " .. self.width .. "x" .. self.height) end -- 使用图形库 local shapes = { Circle.new(5), Rectangle.new(4, 6), Circle.new(3) } for _, shape in ipairs(shapes) do shape:draw() end

练习

  1. 扩展图形库,添加更多形状(如三角形)和其他方法(如计算面积)。
  2. 实现一个简单的动物层次结构,包括不同种类的动物和它们的特定行为。
  3. 创建一个基本的银行账户系统,支持不同类型的账户(如储蓄账户、支票账户)和常见的银行操作。

通过本章的学习,你应该能够在 Lua 中实现面向对象编程的核心概念,并应用这些概念来设计和构建更复杂的系统。记住,虽然 Lua 不是一个传统的面向对象语言,但它提供了足够的灵活性来实现强大的面向对象设计。