只读属性
本课属于 Coddy GDScript 学习旅程的“面向对象编程”单元。第 29 课,共 65 课。
有些值应该可以从外部读取,但不能被赋值:例如在对象创建时只设置一次的 ID,或者根据其他数据计算出的值,例如面积或总数。具有 get 块且没有 set 块的属性可以实现这一点:
# 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 赋值不会报错,但也不会改变任何内容,因为 getter 会一直返回 _number:
var ticket := Ticket.new(42)
ticket.number = 7
print(ticket.number) # 42计算属性本身没有值:每次读取时,它的 getter 都会计算出值,因此它始终与其来源数据保持一致:
# 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 类在 order.gd 中将 ID 存储在 _id 中,并将每个订单项的总价(价格乘以数量)存储在 _line_totals 中。使用 get 块将它的四个公共属性设为只读:
order_id返回_id。subtotal返回_line_totals中各项的总和。- 当小计大于或等于
50时,shipping返回0;否则返回5。 total返回小计加运费。
提供的代码会读取订单 ID、商品数量,然后为每件商品读取一行 price quantity。每读取一件商品后,它都会输出小计、运费和总价。最后,它会尝试将四个属性都设为 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 在线编译器