Lua-object-oriented

提供:Dev Guides
移動先:案内検索

Lua-オブジェクト指向

OOPの概要

オブジェクト指向プログラミング(OOP)は、現代のプログラミング時代に使用される最も使用されているプログラミング手法の1つです。 OOPをサポートする多くのプログラミング言語があります。

  • C++
  • Java
  • Objective-C
  • スモールトーク
  • C#
  • Ruby

OOPの機能

  • クラス-クラスは、オブジェクトを作成するための拡張可能なテンプレートであり、状態の初期値(メンバー変数)と動作の実装を提供します。
  • オブジェクト-それはクラスのインスタンスであり、それ自体に割り当てられた個別のメモリを持っています。
  • 継承-それは、あるクラスの変数と関数が別のクラスに継承される概念です。
  • *カプセル化-それはクラス内のデータと機能を組み合わせるプロセスです。 関数の助けを借りて、クラスの外部でデータにアクセスできます。 データ抽象化とも呼ばれます。

LuaのOOP

Luaのテーブルとファーストクラス関数を使用して、Luaにオブジェクト指向を実装できます。 関数と関連データをテーブルに配置することにより、オブジェクトが形成されます。 継承はメタテーブルの助けを借りて実装でき、存在しない関数(メソッド)および親オブジェクトのフィールドのルックアップメカニズムを提供します。

Luaのテーブルには、その値に依存しない状態やアイデンティティなどのオブジェクトの機能があります。 同じ値を持つ2つのオブジェクト(テーブル)は異なるオブジェクトです。一方、オブジェクトは異なる時間に異なる値を持つことができますが、常に同じオブジェクトです。 オブジェクトと同様に、テーブルには、誰が作成したか、どこで作成されたかに依存しないライフサイクルがあります。

実世界の例

オブジェクト指向の概念は広く使用されていますが、適切かつ最大の利益を得るためには明確に理解する必要があります。

簡単な数学の例を考えてみましょう。 多くの場合、円、長方形、正方形などのさまざまな形状で作業する状況に遭遇します。

シェイプには、共通のプロパティエリアを含めることができます。 そのため、共通プロパティエリアを使用して、ベースオブジェクトシェイプから他のシェイプを拡張できます。 各図形には独自のプロパティと関数を設定できます。たとえば、長方形はプロパティとして長さ、幅、面積、および関数としてprintAreaとCalculateAreaを設定できます。

単純なクラスを作成する

3つのプロパティ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

上記の例では、基本クラスSquareからRectangleとSquareの2つの派生クラスを作成しました。 派生クラスで基本クラスの機能をオーバーライドできます。 この例では、派生クラスは関数printAreaをオーバーライドします。