静态成员
有时在进行对象的操作时,我们可能会希望无论怎样修改,同一个类的不同对象间共享同样的数据,而共享的数据我们就叫做静态成员
类的成员分为两种:
实例成员:每个对象都有一份,各个对象间数据独立,必须创建该类的实例才能够访问。
静态成员:直接属于类本身,所有对象共享一份,可以通过类名访问(虽然也能通过实例访问,但不推荐)
因此,@export和@onready注解并不能用在静态变量上,也无法将局部变量或匿名函数声明为静态
父类的静态成员也能够在子类中访问
静态成员包括静态变量和静态方法,使用static关键字定义静态成员
static var a
static func foo():
pass静态变量也可以指定类型,设置getter和setter函数,但不能在访问器中访问实例成员,调用实例方法
static var a: int:
get:
return a
set(value):
a = value我们知道,self表示的是当前类的实例,而静态方法直接属于类,无法访问当前类的实例成员(不依赖具体对象)
因此静态方法中除了不能使用类的实例成员外,也不能使用self(没有“当前实例”的概念)
当然,这并不代表静态方法完全不能访问实例成员,静态方法自己不能访问类的实例成员(因为没有 self ),但如果你通过参数传进来一个对象,就可以照样访问这个对象的实例成员,无论这个对象是不是当前类的实例。
因此,静态方法适合用于编写工具方法,不需要创建类的实例直接使用类名就能使用它们
static func add(a: int, b: int) -> int:
return a + b
static func is_name_starts_with(node: Node, prefix: String) -> bool:
return node.name.begins_with(prefix)静态属性在所有类的实例中共享状态,因为它是属于类而非实例的
# student.gd
class_name Student
static var class_size: int = 0
var name: String
var id: int
func _init(name: String) -> void:
self.name = name
class_size += 1
id = class_size
# main.gd
extends Node
func _ready():
var student1 := Student.new("张三")
var student2 := Student.new("李四")
print(student1.id) # 1
print(student2.id) # 2
print(Student.class_size) # 2
# 尽管可以这样访问,但不推荐
print(student1.class_size) # 2
print(student2.class_size) # 2练习
创建一个名为
Counter的类,包含一个静态变量count,用于统计创建了多少个Counter实例。提示:每当调用
Counter.new()创建一个实例时,记得在_init()中更新count设计一个名为
MathTool的类,添加两个静态方法:add(a: int, b: int):返回两个整数的和is_even(n: int):返回这个数是不是偶数
创建一个
Student类,定义:静态变量
next_id,用于给每个学生分配一个唯一的id每个学生实例有
name和id字段构造函数需求一个参数,学生的名字
每次创建新学生时初始化学生的名字,并自动递增
next_id赋给该学生
想一想:你是否遇到过在项目中使用静态方法或静态变量的场景?写一个简单的例子或思路,用静态成员去「记录」或「工具化」你的逻辑,比如记录游戏中总共击败了多少敌人