読み取り専用プロパティ
CoddyのGDScriptジャーニー「オブジェクト指向プログラミング」セクションの一部。レッスン 29/65。
値によっては、外部から読み取れるものの、代入はできないようにする必要があります。たとえば、オブジェクトの作成時に一度だけ与えられるIDや、面積や合計のように、ほかのデータから算出される値です。setブロックを持たず、getブロックを持つプロパティを使うと、これを実現できます。
# ticket.gd
class_name Ticket
extends RefCounted
var _number: int
var number: int:
get:
return _number
func _init(start_number: int) -> void:
_number = start_numberコンストラクターは値をプライベートな_numberに保存し、パブリックなnumberはその値を返すだけです。外部からnumberに代入してもエラーにはなりませんが、ゲッターは_numberを返し続けるため、何も変わりません:
var ticket := Ticket.new(42)
ticket.number = 7
print(ticket.number) # 42計算プロパティは独自の値を持ちません。ゲッターは読み取られるたびに値を計算するため、元となるデータと常に一致します。
# room.gd
class_name Room
extends RefCounted
var width: int = 4
var length: int = 5
var area: int:
get:
return width * lengthvar room := Room.new()
print(room.area) # 20
room.width = 6
print(room.area) # 30単純なvar areaは、widthまたはlengthが変わるたびに手動で更新する必要があり、更新を一度でも忘れると値が間違ったままになります。計算されるareaは古くなることがなく、誰も間違った値を代入できません。
すべてのオブジェクトで同じで、決して変わらない値には、クラス内の定数を使います: const MAX_GUESTS = 4。定数への代入は、プログラムの実行前に報告されます。
チャレンジ
簡単order.gd 内の Order クラスは、ID を _id に、各明細の合計(価格と数量の積)を _line_totals に保存します。get ブロックを使って、4 つの公開プロパティを読み取り専用にしてください。
order_idは_idを返します。subtotalは_line_totalsの合計を返します。shippingは、小計が50以上の場合は0を、それ以外の場合は5を返します。totalは小計と送料の合計を返します。
与えられたコードは、注文 ID、商品の個数、続いて商品ごとに price quantity の行を読み込みます。各商品を読み込むたびに、小計、送料、合計を出力します。最後に、4 つのプロパティすべてに 0 を設定しようとしてから、ID と合計を出力します。これらの値は変更されていないはずです。ID が 7 で、商品が 12 2 と 30 1 の場合、次のように出力されます。
Subtotal 24, shipping 5, total 29
Subtotal 54, shipping 0, total 54
Order #7: 54コードは order.gd に記述してください。main.gd には与えられた入力/出力コードが含まれており、編集できません。
自分で試してみよう
extends Node
func _ready():
# 用意された入出力コード:そのままにしておく
var order := Order.new(int(OS.read_string_from_stdin()))
var count := int(OS.read_string_from_stdin())
for i in count:
var parts := OS.read_string_from_stdin().split(" ")
order.add_item(int(parts[0]), int(parts[1]))
print("Subtotal %d, shipping %d, total %d" % [order.subtotal, order.shipping, order.total])
# 読み取り専用プロパティを上書きしようとするコード
order.order_id = 0
order.subtotal = 0
order.shipping = 0
order.total = 0
print("Order #%d: %d" % [order.order_id, order.total])
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
オブジェクト指向プログラミングのすべてのレッスン
自分で練習してみよう: GDScriptオンラインコンパイラ