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

Введение в ООП

Объектно-ориентированное программирование (ООП) - один из наиболее часто используемых методов программирования в современную эпоху программирования. Существует ряд языков программирования, поддерживающих ООП, в том числе:

  • C++
  • Java
  • Objective-C
  • Smalltalk
  • C#
  • Ruby

Особенности ООП

  • Class - Класс - это расширяемый шаблон для создания объектов, предоставляющий начальные значения для состояния (переменные-члены) и реализации поведения.

  • Objects - Это экземпляр класса, для которого выделена отдельная память.

  • Inheritance - Это концепция, согласно которой переменные и функции одного класса наследуются другим классом.

  • Encapsulation- Это процесс объединения данных и функций внутри класса. Доступ к данным можно получить вне класса с помощью функций. Это также известно как абстракция данных.

ООП в Lua

Вы можете реализовать объектную ориентацию в Lua с помощью таблиц и функций первого класса Lua. Помещая функции и связанные данные в таблицу, формируется объект. Наследование может быть реализовано с помощью метатаблиц, обеспечивающих механизм поиска несуществующих функций (методов) и полей в родительских объектах.

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

Пример из реального мира

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

Рассмотрим простой математический пример. Мы часто сталкиваемся с ситуациями, когда работаем с разными формами, такими как круг, прямоугольник и квадрат.

Фигуры могут иметь общее свойство Area. Таким образом, мы можем расширить другие формы из формы базового объекта с помощью области общих свойств. Каждая из фигур может иметь свои собственные свойства и функции, например, прямоугольник может иметь свойства length, width, area в качестве свойств и printArea и calculateArea в качестве функций.

Создание простого класса

Ниже показана простая реализация класса для прямоугольника с тремя свойствами: area, length и width. Он также имеет функцию 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, как показано выше, с помощью другого нового метода с помощью метатаблиц. Все переменные-члены и функции базового класса сохраняются в производном классе.

-- 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.