Luaのオブジェクト指向機能の紹介
オブジェクト指向の機能
- クラス。クラスは、状態(メンバ変数)の初期値や動作の実装を提供するオブジェクトを作成するために使用される拡張可能なテンプレートです。
- オブジェクト。クラスのインスタンスであり、それとは別にメモリが割り当てられている。
- インヘリタンス。あるクラスの変数や関数が他のクラスに継承される概念です。
- カプセル化。データと関数を組み合わせたクラス内のメソッドのことです。データは関数の助けを借りてクラスの外からアクセスすることができる。データの抽象化とも呼ばれる。
LuaのOOP
LuaのテーブルとLuaの第一級関数でオブジェクト指向を実装する。オブジェクトは、関数と関連するデータをテーブルに挿入することで形成されます。メタテーブルの助けを借りて継承を実装することができます。メタテーブルは、存在しない関数(メソッド)や親オブジェクトのフィールドを検索する機構を提供します。
Luaのテーブルには、このようなステートオブジェクトと、値に依存しないプロパティであるアイデンティティオブジェクトがあります。同じ値を持つ2つのオブジェクト(テーブル)でも、オブジェクトは異なる値で持つことができますが、それは常に同じオブジェクトである。それは、オブジェクトテーブルのライフサイクルを持つようなもので、独立して作成または作成されます。
実際の例
オブジェクト指向の概念は幅広いですが、理解して最大限に活用することが重要です。
簡単な数学の例で考えてみましょう。私たちはしばしば、円、長方形、正方形といったさまざまな形の中で作業をする場面に遭遇します。
図形は共通のプロパティ領域を持つことができます。したがって、共通のプロパティ領域を持つベースオブジェクトのシェイプから、他のシェイプを拡張することができるのです。各図形は、長方形が長さ、幅、面積などのプロパティを持ち、関数としてprintAreaやcalcAreaを持つように、独自のプロパティと関数を持つことができます。
簡単なクラスを作成する
簡単なクラスは、以下のような3つのプロパティarea, length, widthを持つ矩形を実装しています。また、計算された面積を表示するための関数printAreaを持っています。
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
オブジェクトの作成
オブジェクトの作成は、クラスのインスタンスにメモリーを割り当てる作業です。各オブジェクトは独自のメモリーを持ち、共通のクラスデータを共有します。
アクセスプロパティ
クラス内のプロパティにアクセスするには、以下のようにドット.演算子を使って属性にアクセスします。
メンバ関数へのアクセス
オブジェクトのメンバー関数にアクセスするには、以下のようにコロン演算子を使用します。
メモリが確保され、初期値が設定される。初期化処理は、他のオブジェクト指向言語よりも構築することができる。上図のように、単純に値を設定する関数である。
完全な例
それでは、オブジェクト指向のLuaを使った完全な例を見てみましょう。
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()
上記のプログラムを実行すると、次のような出力が得られます。
Luaにおける継承
継承とは、形状を単純に長方形、正方形などに拡張した基本オブジェクトの扱いである。実世界で基本的な性質や機能を共有し、拡張するためによく使われる。
簡単なクラスの拡張を見てみましょう。以下のようなクラスがあります。
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
正方形クラスに拡張できる形状は以下の通りです。
-- 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
基本関数のオーバーロード
以下のように、ベースクラスの関数をオーバーロードすることで、クラスを派生させる代わりにベースクラスの関数を使用し、それ自体を実装することができます。
function Square:printArea ()
print("The area of square is ",self.area)
end
継承の完全な例
Luaで拡張できる簡単なクラスの実装は、上記のように別の新しいメソッドをメタ化しています。ベースクラスのすべてのメンバ変数と関数は、派生クラスで保持されます。
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 of square is 100
The area of Rectangle is 200
上記の例では、基底クラスSquareから2つの派生クラスRectangleとSquareを作成しました。したがって、派生クラスは、ここで基底クラスの機能を変更することができます。この実装例では、派生クラスが関数printAreaを置き換えることになります。
関連
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン