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추상화: 추상화(Abstraction)은 복잡한 현실 문제를 간소화하는 방법으로, 구체적인 문제에 가장 적합한 클래스 정의를 찾고, 가장 적합한 상속 수준에서 문제를 설명할 수 있습니다.

Lua의 상대적 객체 지향

우리는 객체는 속성과 메서드로 구성되어 있다는 것을 알고 있습니다. LUA에서 가장 기본적인 구조는 테이블이며, 따라서 객체의 속성을 설명하기 위해 테이블을 사용해야 합니다.

lua의 function은 메서드를 나타내는 데 사용될 수 있습니다. 따라서 LUA의 클래스는 테이블을 통해 나타낼 수 있습니다. + function을 통해 모의할 수 있습니다.

thừa kế는 metatable을 통해 모의할 수 있습니다(추천하지 않습니다. 대부분의 경우, 기본적인 객체를 모의하는 데는 충분합니다).

Lua에 있는 테이블은 어떤 의미에서는 객체와 같습니다. 객체와 마찬가지로 테이블도 상태(멤버 변수)를 가지고 있으며, 객체의 값과 독립된 본성을 가지고 있습니다. 특히 두 가지 다른 값을 가진 객체(table)는 두 가지 다른 객체를 나타냅니다. 객체는 다른 시간에 다른 값을 가질 수 있지만, 그것은 항상 하나의 객체입니다. 객체와 마찬가지로 테이블의 생명주기는 그것이 어떻게 생성되었는지, 어디서 생성되었는지와 관계가 없습니다. 객체는 그들의 멤버 함수를 가지고 있으며, 테이블도 마찬가지로 함수를 가집니다:

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

이 정의는 새로운 함수를 생성하고 Account 객체의 withdraw 영역에 저장합니다. 그런 다음 다음과 같이 호출할 수 있습니다:

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