Menu
CoddyTech

按约定设为私有

本课属于 Coddy GDScript 学习旅程的“面向对象编程”单元。第 13 课,共 65 课。

GDScript 没有 private 关键字:对象的每个属性和方法都可以从其他脚本访问。Godot 的惯例是在名称前加下划线。下面的 _coins 和 _is_valid() 仅供类自己的代码使用:

# wallet.gd
class_name Wallet
extends RefCounted

var _coins: int = 0

func add(amount: int) -> void:
	if _is_valid(amount):
		_coins += amount

func spend(amount: int) -> bool:
	if not _is_valid(amount) or amount > _coins:
		return false
	_coins -= amount
	return true

func get_coins() -> int:
	return _coins

func _is_valid(amount: int) -> bool:
	return amount > 0

其他脚本会使用公共方法,这些方法会检查每次更改:spend() 不会扣除超过钱包余额的金币,因此金币数量永远不会低于零。

var wallet := Wallet.new()
wallet.add(50)
wallet.add(-20)
print(wallet.spend(80)) # false
print(wallet.get_coins()) # 50

下划线是一种约定,不是锁:wallet._coins = -999 可以正常运行,不会报错。是否遵守约定,取决于编写其他脚本的人,所以不要在类的外部读取或修改带下划线的成员。

你已经了解了 Godot 自带的两个下划线名称:_ready() 和 _init() 由引擎调用,而不是由你自己的代码调用。

challenge icon

挑战

简单

完成 User 类,并将代码写在 user.gd 中。它会将密码保存在私有属性 _password 中,只有它自己的代码会访问这个属性。

  • 构造函数会保存初始密码
  • check_password(attempt) 会返回 attempt 是否与密码匹配
  • 私有辅助函数 _is_strong(candidate) 会返回 candidate 是否至少包含 6 个字符
  • change_password(old_password, new_password) 会更改密码,并且只有在 old_password 正确且 new_password 足够强时才返回 true。否则,它不会更改任何内容,并返回 false

提供的代码会读取初始密码、后续命令的数量,以及命令 check PASSWORD 和 change OLD NEW。密码为 godot4,命令为 change godot4 abc、change wrong longenough 和 check godot4 时,输出为:

Password not changed
Password not changed
Access granted

将你的代码写在 user.gd 中。main.gd 包含提供的输入/输出代码,不能编辑。

亲手试试

extends Node

func _ready():
	# 已提供的输入输出代码:保持原样。
	var user := User.new(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(" ")
		if parts[0] == "check":
			print("Access granted" if user.check_password(parts[1]) else "Access denied")
		elif user.change_password(parts[1], parts[2]):
			print("Password changed")
		else:
			print("Password not changed")
quiz icon自我测试

这节课包含一个小测验。开始学习即可作答,并记录你的进度。

面向对象编程中的所有课

自己练习: GDScript 在线编译器