[Unity中文课堂教程] C#中级编程 - 02 - 静态
原教程视频地址:
《[Unity中文课堂教程预告片] C#中级编程_哔哩哔哩_bilibili》
内容短小精悍简练,每节只有几分钟。很适合用来预习和复习。
主要代码内容
情况一:调用实例类中的静态属性或方法
说明:加了
static
关键字,称为静态属性或方法,否者统称为实例属性或方法。以下代码略过命名空间。
脚本①:被调用
public class Exercise_4_2 : MonoBehaviour
{
public static int num_0 = 0;
void Start()
{
num_0++; // 类内部可随意调用静态属性,或方法。
}
public static void log_0()
{
Debug.Log("调用了静态方法");
}
public void log_1()
{
log_0(); // 静态在类中不影响,可随意访问调用。
num_0 = 100;
Debug.Log("调用了普通方法");
}
}
脚本②:调用脚本①
public class Exercise_4_3 : MonoBehaviour
{
void Start()
{
Debug.Log(Exercise_4_2.num_0); // 打印静态属性
Exercise_4_2.log_0(); // 调用静态方法
// Exercise_4_2.log_1(); // 不可调用实例方法
Exercise_4_2 him = gameObject.AddComponent<Exercise_4_2>();
him.log_1(); // 实例对象只可调用非静态方法(实例方法)。
// him.num_0 = 10; // 静态属性不能使用实例对象访问,也就是不可读写。
// him.log_0(); // 静态方法也不能调用。
}
}
- 总结:
- 用实例类名可以调用静态属性或静态方法,不可调用实例属性和实例方法。
- 用实例对象可以调用实例属性和实例方法,不可调用静态属性或静态方法。(也就算与上面一条相反)
- 类内访问不会受限制,不需要添加前缀,正常直接访问。
注意,无论脚本是否挂载到对象。这属于C#的语法,脚本只要存在unity工程目录内都会被一同编译起作用。
- 类的静态是属于类本身的,唯一的、共同的。而类的实例是属于对象的,每个实例化对象都是独立的、不同的。
利用静态共同的特点,可以将脚本挂载到对象上,然后使用静态属性累加。就可统计创建了多少对象。(上述例子)
- 静态后的一大特点,就是可以直接使用类名调用方法。这或是最简单的用法了。(结果上有点像声明全局?)
情况二:调用静态类中的静态属性或方法。
脚本①:
public static class Exercise_4_4 // 静态类不可继承 MonoBehaviour ,意味着不能挂载对象
{
public static int num_1 = 3; // 静态类只可创建静态属性和方法
static void Start()
{
num_1++;
}
public static void log_0() // 命名空间和其他类相互独立
{
Debug.Log("这是一个静态类");
}
}
脚本②:
public class Exercise_4_3 : MonoBehaviour
{
void Start()
{
Debug.Log(Exercise_4_4.num_1); // 打印静态属性
Exercise_4_4.log_0(); // 打印静态属性
// Exercise_4_4 him_0 = gameObject.AddComponent<Exercise_4_4>(); // 不能创建静态类对象
}
}
- 总结特点:
- 创建类时也加上
static
关键字的话,类内所有属性和方法也要加static
关键字,否者会报错。 - 静态类名也不能继承unity的父类
MonoBehaviour
,代表不能挂载对象,也就不具有Start()
等特殊功能的方法。 - 静态类名也不能创建实例化对象。
总结来看静态类名好像没什么用。
情况三:使用静态类名调用静态对象再调用非静态属性或方法
- 如果并不想将整个类都设为静态类,想保留类中有静态也有实例,但又想在不用实例化的情况下调用实例属性或方法。可以在类中创建静态对象。通过这个静态对象访问类中的实例内容。
脚本①:
public class Exercise_4_2 : MonoBehaviour
{
public static Exercise_4_2 exercise_4_2; // 静态类对象
void Start()
{
if (exercise_4_2 == null)
exercise_4_2 = this; // 赋值静态类对象
}
public void log_1() // 实例方法
{
Debug.Log("调用了 exercise_4_2 : " + exercise_4_2);
}
}
脚本②:
public class Exercise_4_3 : MonoBehaviour
{
void Start()
{
// Exercise_4_2.log_1(); // 非静态方法不能直接用类名调用,
if (Exercise_4_2.exercise_4_2 != null) // 前提是静态属性拿到静态类对象,否者会报错,
Exercise_4_2.exercise_4_2.log_1(); // 可使用静态属性可调用非静态方法……
// Debug.Log(Exercise_4_2.exercise_4_2.num_0); // 还是不可调用静态属性
}
}
- 总结特点:
- 相当于提前创建了一个共用全局的类对象,方便调用。
- 使用前记得判断静态对象是否已获取,否者会空引用,报错。1.
- 和实例对象一样,不可使用静态对象访问静态属性,会报错。