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中操作
相关推荐
TT哇9 小时前
【Java】数组的定义与使用
java·开发语言·笔记
黑叶白树10 小时前
包和模块(上) python复习笔记
开发语言·笔记·python
L_Z_J_I10 小时前
超子物联网HAL库笔记:多指针定位+循环收发缓冲区方案设计
笔记
我是水怪的哥10 小时前
一些有用的科研数据网站
经验分享·笔记
zhilanguifang11 小时前
ERC论文阅读(02)--SAC;-LSTM论文阅读笔记
论文阅读·笔记·lstm
北冥没有鱼啊12 小时前
UE5 射线折射
游戏·ue5·游戏引擎·ue4
尘佑不尘14 小时前
shodan5,参数使用,批量查找Mongodb未授权登录,jenkins批量挖掘
数据库·笔记·mongodb·web安全·jenkins·1024程序员节
Iqnus_12315 小时前
vue下载安装
前端·vue.js·笔记
CLCNboss15 小时前
Mac安装Ruby
开发语言·经验分享·笔记·macos·ruby
呵呵哒( ̄▽ ̄)"17 小时前
尚硅谷-react教程-求和案例-优化3-整合UI组件和容器组件-总结优化-笔记
前端·笔记·react.js