命名規則
CoddyのLuaジャーニー「オブジェクト指向プログラミング」セクションの一部。レッスン 43/70。
Luaでは、すべてのテーブルのfieldにデフォルトでPublicにアクセスできます。誰でもself.healthを直接読み取ったり変更したりできます。LuaはPrivateを強制しませんが、プログラマーは命名規則を使用して意図を伝えます。つまり、どのfieldをinternalな実装の詳細として扱うべきかを示します。
標準的な慣例では、private フィールドにはアンダースコアを付けます。
local Player = {}
Player.__index = Player
function Player:new(name)
local obj = {
name = name, -- パブリック: 直接アクセスしてよい
_health = 100, -- プライベート: 代わりにメソッドを使う
_score = 0 -- プライベート: 内部追跡用
}
setmetatable(obj, Player)
return obj
end
function Player:getHealth()
return self._health
end
function Player:takeDamage(amount)
self._health = self._health - amount
endアンダースコアは Lua の動作を変えません。player._healthには依然として技術的にはアクセスできます。しかし、これは他のプログラマー(そして将来の自分自身)への明確な警告として機能します。「この field は private として扱うものです。代わりに methods を通じてアクセスしてください。」
この規約が重要なのは、インターフェース(他のコードが使用すべきもの)と実装(内部でどのように動作するか)を分離するためです。後から検証を追加したり、health の保存方法を変更したりする必要が生じても、変更するのはメソッドだけです。:getHealth()を使用しているコードは、変更なしでそのまま動作し続けます。
チャレンジ
簡単アンダースコア命名規則を使って、どのフィールドが Private であるべきかを適切に示す BankAccount クラスを作成しましょう。
コードを2つのファイルに分けて整理します。
BankAccount.lua:account 情報を管理するクラスを作成します。コンストラクター:new(ownerName, initialBalance)では、所有者の名前を Public field(owner)として、残高を Private field(_balance)として保存します。次の3つの methods を含めてください。:getBalance():current balance を返す:deposit(amount):_balanceに amount を加える:getOwner():所有者の名前を返す
main.lua:BankAccount module を Require し、入力から所有者の名前、initial balance、deposit amount を読み取ります。account を Create し、deposit を行ってから、所有者と final balance を Print します。
3つの入力を受け取ります。
- 所有者の名前
- initial balance(number)
- deposit amount(number)
出力には、所有者と deposit 後の final balance を示す2行を表示します。
Owner: {ownerName}
Balance: {finalBalance}たとえば、入力が Maria、500、150 の場合、出力は次のようになります。
Owner: Maria
Balance: 650覚えておきましょう。_balance の先頭にあるアンダースコアは、この field を directly access するのではなく、:getBalance() や :deposit() のような methods を通して access すべきであることを他のプログラマーに示します。アンダースコアのない owner field は、Public に access して問題ないことを示します。
自分で試してみよう
-- BankAccountモジュールを読み込む
local BankAccount = require('BankAccount')
-- 入力を読み取る
local ownerName = io.read()
local initialBalance = tonumber(io.read())
local depositAmount = tonumber(io.read())
-- TODO: ownerNameとinitialBalanceで新しいBankAccountを作成する
-- TODO: depositAmountを使って入金する
-- TODO: 指定された形式で所有者と最終残高を出力する
-- 形式:
-- Owner: {ownerName}
-- Balance: {finalBalance}
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
オブジェクト指向プログラミングのすべてのレッスン
自分で練習してみよう: Luaオンラインコンパイラ