目录
类
- 是面向对象编程的最基础的概念,是计算机程序实现数据信息封装的基础
- Godot大部分内容都继承于Object,而Object就是Godot中基础的类,如果不写extends来指定继承哪个类,默认继承于Object
- 我们自定义的类最终都要继承于Object
关键字class_name
- 可以定义一个全局类,全局类在Godot代码中的任意部分都可以访问
- <类名>.成员名,访问成员
- 类相当于我们自己定义的一种变量类型
- <类名>.new()创建出一个类实例
- 继承于Object类的实例就像一个游戏物体,被创建出来要释放删除,否则一直存在于内存中
除了为类定义方法,我们也可以为类定义属性字段
- 属性就是类内部的变量,用于存储数据
实例释放前后的打印
- 实例释放前,输出文本Object和数字,后面的数字就是实例的唯一ID,Godot中所有类都有一个唯一ID
- 实例释放后,输出Freed Object
Refcounted
- 我们通过调用free函数实现删除实例,这个free函数就是Godot中的Object类提供的一个函数
- Object默认不会自动释放,需要我们在用不到这个实例之后手动调用free函数
- 我们将类继承于RefCounted这个类
- RefCounted同样继承于Object类,只不过这个类的内存是交给Godot管理的,在RefCounted检查到自身引用为0的时候,就会自动释放自身
- 继承于RefCounted的类也会有一样的特点
- 这里的my_class就是一个对实例的引用当_ready函数执行结束后,my_class这个变量会被Godot释放,同时这个变量所引用的Myclass实例的引用计数-1
- 当引用计数归0时,Godot会立刻删除这个实例对象
RefCounted维护了一个引用计数器
- 由于Object是一个引用类型的数据,我们定义的变量持有的只是一个内存地址
- 这个地址才是类实例数据存放的位置,RefCounted就是检查程序中有多少个变量引用了当前自身这个地址
get_reference_count
- 通过get_reference_count检查当前实例有多少个引用
- 因为没有任何变量引用实例的地址就再也访问不到程序的内存了,所以RefCounted会认为当前实例已经用不到了,随后就会释放自身
- 这里的my_class就是对类实例的一个引用,返回1,也就是说整个程序只有一个对这个实例的引用
- 定义一个新变量,内容为my_class,这时这个新变量也成了对这个实例的一个引用
- 最后,将ref_my_class的值改为null,也就是这个变量不再存储对这个实例的引用,引用计数就会-1
类是引用类型数据
- 类的实例是一个引用类型数据,引用类型数据的特点就是变量存储的,不是数据的实际内容,而是程序内存中的一个地址
- 这个地址指向了类实例的实际数据存储的位置
- 声明一个新变量my_class2,它的值为my_class,实际上,就是my_class2保存的内容变得和my_class一样
- my_class实际上保存的是一个地址,这个地址是我们使用Nuew函数实例化出来的类实例
- 所以最后,my_class和my_class2存储的都是这个类实例的内存地址
- 我们修改my_class中的id值为100,然后点打印,这个id值是我们刚刚在全局类Myclass中声明的一个整数属性字段
- 在下面,我们又声明了my_class2,它的值为my_class,我们修改my_class2的id属性,输出后发现,my_class2的改动影响了my_class
- 这也证明了实际我们的my_classs是全局类的Myclass实例的一个地址, 在定义my_class2时,只不过将同一地址赋值进去
- 多个变量指向同一个类实例对象,所以对my_class2的修改也会影响到my_class
class关键字
- 我们通过class_name定义的是全局类,全局类在Godot整个项目内都可以通过代码实例化
- 而我们可以通过class关键字,来定义一个内部类
- 内部类只有当前定义部类的脚本中才可以实例化
- class后面加上类的名称,内部类默认继承于Object
- 同样可以使用extends关键字来指定这个内部类继承于哪个父类
- 内部类的代码作用域和脚本的作用域不同,是两个独立的作用域,因此内部类无法访问脚本中的全局变量
静态类型
- 静态变量使用static关键字,在定义变量的var关键字之前对其修饰,Godot就会将变量声明为静态变量
- 静态变量就是程序运行期间,保持其存在和值的变量
- 即,静态变量的值是所有类实例统一的
- 我们用new关键字实例化创建两个类的实例,这两个实例都是独立的
- 最后输出的内容是两个不同的数值,表明两个类实例独立
- 将num改成静态变量cnt
- 最后输出同样的值,也就是我们最后赋值的内容
- 对静态变量的修改,影响是全局的
静态方法
- 在func关键字前加上static修饰符,可以声明一个静态方法
- 我们可以直接通过类名访问静态变量或静态方法
- 无法访问非静态变量
- 因为如果我们不实例化,这个非静态变量数据是不存在于程序内存中的
- 而静态变量在程序初始化时就被创建了,因此无须我们手动实例入这个类的实例
- 可以根据这种特性制作一些工具类
静态方法只能访问静态变量
- 由于静态方法可以在不实例化时调用,所以静态方法只能访问静态变量
- 如果类没有实例化,非静态变量是不存在于程序内存的,所以为了避免错误,静态方法就无法访问非静态变量
- 这里的user_name2是一个非静态变量,如果以为要对其进行修改,无法在静态方法string_add中操作