English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
オブジェクト指向プログラミング(Object Oriented Programming、OOP)は非常に人気のあるコンピュータプログラミングアーキテクチャです。
以下のいくつかのプログラミング言語はオブジェクト指向プログラミングをサポートしています:
C++
Java
Objective-C
Smalltalk
C#
Ruby
1)封装:ある実体の情報、機能、応答を独立したオブジェクトに収めることができる特性です。
2)継承:継承の方法は、元のプログラムを変更せずに拡張するために使用されます。これにより、元の機能が保存され、新機能も拡張されます。これにより、コードの重複を減らし、ソフトウェア開発の効率を向上させます。
3)多態:同じ操作が異なるオブジェクトに適用されると、異なる解釈が行われ、異なる実行結果が得られます。実行時には、基底クラスのポインタを通じて、派生クラス内のメソッドを呼び出すことができます。
4)抽象:抽象(抽象化)は複雑な現実問題を簡素化する手段であり、具体的な問題に対して最適なクラス定義を見つけることができ、最適な継承レベルで問題を解釈することができます。
私たちは、オブジェクトは属性とメソッドで構成されていることを知っています。LUAでは最も基本的な構造はテーブルであり、したがって、オブジェクトの属性を説明するためにテーブルを使用する必要があります。
Luaのfunctionはメソッドを表すために使用できます。したがって、LUAのクラスはテーブルを通じて表されます。 + functionでシミュレートできます。
継承はmetatableでシミュレートできます(推奨しませんが、基本的なオブジェクトをシミュレートするのに十分なことが多いです)。
Luaでのテーブルはある意味ではオブジェクトでもあります。オブジェクトのように、テーブルにも状態(メンバ変数)があり、また独立した性質を持ち、異なる値を持つオブジェクト(テーブル)は異なるオブジェクトを表します。オブジェクトは異なる時期に異なる値を持つこともありますが、常に同じオブジェクトです。オブジェクトと同様に、テーブルのライフサイクルはそれがどこで作成され、どのように作成されたかに関係ありません。オブジェクトにはメンバ関数があり、テーブルにもあります:
Account = {balance = 0} function Account:withdraw(v) Account.balance = Account.balance - v end
この定義は、新しい関数を作成し、Accountオブジェクトのwithdraw領域に保存します。以下のように呼び出すことができます:
Account.withdraw(100.00)
以下の簡単なクラスには3つの属性があります: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
継承とは、一つのオブジェクトが別のオブジェクトの属性とメソッドを直接使用することです。これにより、基本クラスの属性とメソッドを拡張できます。
以下に簡単な継承例を示します:
-- メタクラス 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 * 幅 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