[Unity中文课堂教程] C#中级编程 - 05 - 构造函数/封装/继承
原教程视频地址:
《[Unity中文课堂教程预告片] C#中级编程_哔哩哔哩_bilibili》
《C#中级编程 - Unity中文课堂 (u3d.cn)》
《C# 继承 | 菜鸟教程 (runoob.com)》
内容短小精悍简练,每节只有几分钟。很适合用来预习和复习。
构造函数
在上一篇《04》笔记中提到过,这次详细做实验。
参考《C#构造函数(超详解,建议收藏!!!)_liu991029的博客-CSDN博客_c#构造函数》
- 构造函数没有返回值(void也不需要),构造函数的命名必须和类名相同,或不设会有一个默认的构造函数。
public class Exercise_4_9
{
public Exercise_4_9()
{
Debug.Log("Exercise_4_9 构造函数");
}
}
- 构造函数也允许重载,即可拥有多个参数不同的构造函数,实例化时根据参数选择执行其中一个执行。
public class Exercise_4_9 : MonoBehaviour
{
public Exercise_4_9()
{
Debug.Log("Exercise_4_9 构造函数");
}
public Exercise_4_9(int num)
{
Debug.Log(num);
}
}
Exercise_4_9 myClass = new Exercise_4_9();
Exercise_4_9 myClass1 = new Exercise_4_9(1);
- 构造函数的“访问修饰符”要设置为
public ,才可被调用,而在实例化时会调用,一般使用new 关键字。如果设置为私有private、protected等 则无法访问(如果不设置默认也是私有),也就无法实例化,会直接报错。重载时同理。
在unity中也可使用泛型gameObject.AddComponent<>() ,另外使用泛型时,即使构造函数是私有也可以调用。不过使用泛型实例化不知如何传参,也就无法选择重载了。
- 构造函数还可以设置为静态的,使用关键字
static ;而且不能写访问修饰符;只会被调用一次;在实例化时,或访问静态内容时调用;不能有参数,也就意味着不能重载,只能有一个。
重点:
虽然没有写访问修饰符,默认为私有private ,按理类中必须要再写一个public 的构造函数。但是这里是允许的,可以只有一个静态构造函数。
毕竟实例化时也可被调用的,前提是静态构造函数没有调用过。
public class Exercise_4_9 : MonoBehaviour
{
public static int num = 0;
public Exercise_4_9()
{
Debug.Log("Exercise_4_9 构造函数");
}
static Exercise_4_9()
{
Debug.Log("Exercise_4_9 静态函数");
}
}
Exercise_4_9.num = 1;
Exercise_4_9 myClass = new Exercise_4_9();
Exercise_4_9 myClass1 = new Exercise_4_9();
- 构造函数在继承时不会被覆盖,子父类的构造函数都会存在并依次调用。(先父类后子类)
public class Exercise_4_10 : Exercise_4_9
{
public Exercise_4_10()
{
Debug.Log("Exercise_4_10 构造函数");
}
}
public class Exercise_4_11 : MonoBehaviour
{
void Start()
{
Exercise_4_10 myClass = new Exercise_4_10();
}
}
- 在微软手册中《构造函数 - C# 编程指南 | Microsoft Docs》,还提到,如果构造函数只有一句,则可以使用表达式主体定义。
封装
参考《C# 封装 | 菜鸟教程 (runoob.com)》《C#中默认访问修饰符_给永远比拿愉快-CSDN博客》
- C# 封装根据具体的需要,设置使用者的访问权限,并通过 访问修饰符 来实现。在类的继承中很重要的概念。
一个 访问修饰符 定义了一个类成员的范围和可见性。C# 支持的访问修饰符如下所示:
public :所有对象都可以访问;private :对象本身在对象内部可以访问;protected :只有该类对象及其子类对象可以访问internal :同一个程序集的对象可以访问;protected internal :访问限于当前程序集或派生自包含类的类型。
继承
- 继承是面向对象程序设计中最重要的概念之一。
- 和python的形式不一样,不需要括号,只需要冒号分隔。
在unity中:
-
每个挂载到游戏对象的脚本,都必须继承父类MonoBehaviour 。 -
有个常用操作,如果想往一个类中添加内容方法或属性,可以基于此类新定义一个派生类。然后其他类都继承此派生类即可。比如:类① 继承了MonoBehaviour ,那之后的脚本只需要继承 类① 即可。
脚本①:(父类)
public class Exercise_4_9 : MonoBehaviour
{
public static int num = 100;
public int num_0 = 10;
private int num_1 = 11;
protected int num_2 = 12;
public static void get_s()
{
Debug.Log("Exercise_4_9 的静态");
}
public int get_num_0()
{
return num_0;
}
private int get_num_1()
{
return num_1;
}
protected int get_num_2()
{
return num_2;
}
}
脚本②:(子类)
public class Exercise_4_10 : Exercise_4_9
{
public static int num1 = 101;
public int num_01 = 20;
private int num_11 = 21;
protected int num_12 = 22;
public static void get_s0()
{
num = 1000;
Debug.Log("Exercise_4_10 的静态" + num);
}
public int get_num_01()
{
Debug.Log(num_0);
Debug.Log(num_2);
get_s();
return num_01;
}
public void get_all()
{
Debug.Log(get_num_0());
Debug.Log(get_num_2());
}
}
脚本③:(实例化)
public class Exercise_4_11 : MonoBehaviour
{
void Start()
{
Exercise_4_10 myClass = new Exercise_4_10();
Exercise_4_9.num = 233;
Debug.Log("Exercise_4_10.num1:" + Exercise_4_10.num1);
Debug.Log("Exercise_4_10.num:" + Exercise_4_10.num);
Exercise_4_10.get_s();
Exercise_4_10.get_s0();
myClass.get_all();
Debug.Log(myClass.get_num_01());
}
}
- 基于访问修饰符,父类(含静态)的属性和方法可直接在子类中访问。不需要前缀,宛如就是在子类中定义似的。
- 子类继承父类的静态后,属于引用。本质上还是父类的静态,如果子类修改了父类的静态,父类会同步修改;反之亦然。
还有覆写等知识点,下一篇再写,发现太多了。
|