Godot中类和静态类型

目录

关键字class_name

除了为类定义方法,我们也可以为类定义属性字段

实例释放前后的打印

Refcounted

RefCounted维护了一个引用计数器

get_reference_count

类是引用类型数据

class关键字

静态类型

静态方法

静态方法只能访问静态变量


  • 是面向对象编程的最基础的概念,是计算机程序实现数据信息封装的基础
  • 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

类是引用类型数据

  • 类的实例是一个引用类型数据,引用类型数据的特点就是变量存储的,不是数据的实际内容,而是程序内存中的一个地址
  • 这个地址指向了类实例的实际数据存储的位置
  1. 声明一个新变量my_class2,它的值为my_class,实际上,就是my_class2保存的内容变得和my_class一样
  2. my_class实际上保存的是一个地址,这个地址是我们使用Nuew函数实例化出来的类实例
  3. 所以最后,my_class和my_class2存储的都是这个类实例的内存地址
  1. 我们修改my_class中的id值为100,然后点打印,这个id值是我们刚刚在全局类Myclass中声明的一个整数属性字段
  2. 在下面,我们又声明了my_class2,它的值为my_class,我们修改my_class2的id属性,输出后发现,my_class2的改动影响了my_class
  3. 这也证明了实际我们的my_classs是全局类的Myclass实例的一个地址, 在定义my_class2时,只不过将同一地址赋值进去
  4. 多个变量指向同一个类实例对象,所以对my_class2的修改也会影响到my_class

class关键字

  • 我们通过class_name定义的是全局类,全局类在Godot整个项目内都可以通过代码实例化
  • 而我们可以通过class关键字,来定义一个内部类
    • 内部类只有当前定义部类的脚本中才可以实例化
  • class后面加上类的名称,内部类默认继承于Object
    • 同样可以使用extends关键字来指定这个内部类继承于哪个父类

  • 内部类的代码作用域和脚本的作用域不同,是两个独立的作用域,因此内部类无法访问脚本中的全局变量

静态类型

  • 静态变量使用static关键字,在定义变量的var关键字之前对其修饰,Godot就会将变量声明为静态变量
  • 静态变量就是程序运行期间,保持其存在和值的变量
    • 即,静态变量的值是所有类实例统一的
  • 我们用new关键字实例化创建两个类的实例,这两个实例都是独立的
  • 最后输出的内容是两个不同的数值,表明两个类实例独立

  • 将num改成静态变量cnt
  • 最后输出同样的值,也就是我们最后赋值的内容
  • 对静态变量的修改,影响是全局的

静态方法

  • 在func关键字前加上static修饰符,可以声明一个静态方法
  • 我们可以直接通过类名访问静态变量或静态方法


  • 无法访问非静态变量
    • 因为如果我们不实例化,这个非静态变量数据是不存在于程序内存中的
  • 而静态变量在程序初始化时就被创建了,因此无须我们手动实例入这个类的实例
  • 可以根据这种特性制作一些工具类

静态方法只能访问静态变量

  • 由于静态方法可以在不实例化时调用,所以静态方法只能访问静态变量
  • 如果类没有实例化,非静态变量是不存在于程序内存的,所以为了避免错误,静态方法就无法访问非静态变量
  • 这里的user_name2是一个非静态变量,如果以为要对其进行修改,无法在静态方法string_add中操作
相关推荐
冰帝海岸3 小时前
01-spring security认证笔记
java·笔记·spring
小二·4 小时前
java基础面试题笔记(基础篇)
java·笔记·python
向宇it4 小时前
【unity小技巧】unity 什么是反射?反射的作用?反射的使用场景?反射的缺点?常用的反射操作?反射常见示例
开发语言·游戏·unity·c#·游戏引擎
芋芋qwq6 小时前
Unity UI射线检测 道具拖拽
ui·unity·游戏引擎
tealcwu6 小时前
【Unity服务】关于Unity LevelPlay的基本情况
unity·游戏引擎
wusong9997 小时前
mongoDB回顾笔记(一)
数据库·笔记·mongodb
猫爪笔记7 小时前
前端:HTML (学习笔记)【1】
前端·笔记·学习·html
Resurgence037 小时前
【计组笔记】习题
笔记
pq113_67 小时前
ftdi_sio应用学习笔记 3 - GPIO
笔记·学习·ftdi_sio
爱米的前端小笔记8 小时前
前端八股自学笔记分享—页面布局(二)
前端·笔记·学习·面试·求职招聘