English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Ориентированный на объекты Lua

Объектно-ориентированное программирование (Object Oriented Programming, OOP) - это очень популярная архитектура компьютерного программирования.

Следующие языки программирования поддерживают объектно-ориентированное программирование:

  • C++

  • Java

  • Objective-C

  • Smalltalk

  • C#

  • Ruby

Особенности объектно-ориентированного программирования

  • 1) Капсуляция: Это свойство, которое позволяет装入一个 единственной сущности информацию, функции и ответы в отдельный объект.

  • 2) Наследование: Методы наследования позволяют расширять программу без изменения исходного кода, сохраняя при этом исходные функции и расширяя новые функции. Это полезно для уменьшения повторного кодирования и повышения эффективности разработки программного обеспечения.

  • 3) Полиморфизм: Одно и то же действие, применяемое к различным объектам, может иметь разное объяснение и привести к различным результатам выполнения. В време выполнения можно вызвать методы, реализованные в производных классах, через указатель на базовый класс.

  • 4) Абстракция: Абстракция - это способ упрощения сложных реальных проблем, она может найти наиболее подходящую классовую определение для конкретных проблем и может объяснять проблемы на наиболее подходящем уровне наследования.

Объектно-ориентированное программирование в Lua

Мы знаем, что объекты состоят из свойств и методов. Основной структурой в LUA является таблица, поэтому нужно использовать таблицу для описания свойств объекта.

Функции в lua могут использоваться для представления методов. Следовательно, классы в LUA можно имитировать с помощью таблицы + функции.

Что касается наследования, его можно имитировать с помощью metatable (не рекомендуется использовать, так как для имитации最基本的 объектов достаточно большинства времени).

Таблицы в Lua являются объектами в определенном смысле. Как и объекты, таблицы имеют состояние (члены переменных); они также обладают независимой природой, особенно когда таблицы с двумя различными значениями представляют два различных объекта; у объекта может быть разное значение в разное время, но он всегда остается объектом; как и объекты, цикл жизни таблицы не зависит от того, что ее создает и где она создается. У объектов есть их члены функции, и у таблиц также есть:

Account = {balance = 0}
function Account:withdraw (v)
    Account.balance = Account.balance - v
end

Этаdefinition создает новую функцию и сохраняет ее в поле withdraw объекта Account, после чего мы можем вызвать ее следующим образом:

Account:withdraw(100.00)

Пример

Следующий простой класс включает в себя три свойства: area, length и breadth, метод printArea используется для вывода результатов вычислений:

-- Мета-класс
Rectangle = {area = 0, length = 0, breadth = 0}
-- Метод производного класса 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
-- Метод производного класса printArea
function Rectangle:printArea ()
  print("Площадь прямоугольника", self.area)
end

Создание объекта

Создание объекта является процессом выделения памяти для примера класса. Каждый класс имеет свою собственную память и совместно использует общие данные.

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

Доступ к свойствам

Мы можем использовать точку(.) для доступа к свойствам класса:

print(r.length)

Доступ к членам функции

Мы можем использовать двоеточие : для доступа к членам функции класса:

r:printArea()

Память выделяется при инициализации объекта.

Полный пример

Ниже мы демонстрируем полный пример面向 объектов на Lua:

-- Мета-класс
Shape = {area = 0}
-- Метод базового класса 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
-- Метод базового класса printArea
function Shape:printArea ()
  print("Площадь: " .. self.area)
end
-- Создание объекта
myshape = Shape:new (nil, 10)
myshape:printArea ()

Выполнение вышеуказанного программного кода возвращает результат:

Площадь составляет 100

Наследование в Lua

Наследование означает, что один объект напрямую использует атрибуты и методы другого объекта. Это можно использовать для расширения свойств и методов базового класса.

Следующий пример демонстрирует простую пример наследования:

-- Мета-класс
Shape = {area = 0}
-- Метод базового класса 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
-- Метод базового класса printArea
function Shape:printArea ()
  print("Площадь: " .. self.area)
end

В следующем примере объект Square наследует класс Shape:

Square = Shape:new ()
-- Метод производного класса new
function Square:new (o, side)
  o = o or Shape:new (o, side)
  setmetatable (o, self)
  self.__index = self
  return o
end

Полный пример

В данном примере мы наследуем простой класс, чтобы расширить методы производного класса, производный класс сохраняет переменные и методы, наследованные от базового класса:

-- Мета-класс
Shape = {area = 0}
-- Метод базового класса 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
-- Метод базового класса printArea
function Shape:printArea ()
  print("Площадь: " .. self.area)
end
-- Создание объекта
myshape = Shape:new (nil, 10)
myshape:printArea ()
Square = Shape:new ()
-- Метод производного класса new
function Square:new (o, side)
  o = o or Shape:new (o, side)
  setmetatable (o, self)
  self.__index = self
  return o
end
-- Метод производного класса printArea
function Square:printArea ()
  print("Площадь квадрата", self.area)
end
-- Создание объекта
mysquare = Square:new (nil, 10)
mysquare:printArea ()
Rectangle = Shape:new ()
-- Метод производного класса 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
-- Метод производного класса printArea
function Rectangle:printArea ()
  print("Площадь прямоугольника", self.area)
end
-- Создание объекта
myrectangle = Rectangle:new (nil, 10, 20)
myrectangle:printArea ()

Выполнение вышеуказанного кода, результат вывода:

Площадь составляет 100
Площадь квадрата составляет 100
Площадь прямоугольника составляет 200

Переопределение функции

В Lua мы можем переопределять функции базового класса, определяя свои реализации в производном классе:

-- Метод производного класса printArea
function Square:printArea ()
  print("Площадь квадрата", self.area)
end