[Unity] C#中级编程 - 05 - 构造函数/封装/继承

[Unity中文课堂教程] C#中级编程 - 05 - 构造函数/封装/继承

原教程视频地址:

《[Unity中文课堂教程预告片] C#中级编程_哔哩哔哩_bilibili》

《C#中级编程 - Unity中文课堂 (u3d.cn)》

《C# 继承 | 菜鸟教程 (runoob.com)》

内容短小精悍简练,每节只有几分钟。很适合用来预习和复习。

构造函数

在上一篇《04》笔记中提到过,这次详细做实验。

参考《C#构造函数(超详解,建议收藏!!!)_liu991029的博客-CSDN博客_c#构造函数》

  1. 构造函数没有返回值(void也不需要),构造函数的命名必须和类名相同,或不设会有一个默认的构造函数。
public class Exercise_4_9
{
	public Exercise_4_9()
    {
		Debug.Log("Exercise_4_9 构造函数");
	}
}
  1. 构造函数也允许重载,即可拥有多个参数不同的构造函数,实例化时根据参数选择执行其中一个执行。
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);	// 只执行第二个构造函数
  1. 构造函数的“访问修饰符”要设置为public,才可被调用,而在实例化时会调用,一般使用new关键字。如果设置为私有private、protected等 则无法访问(如果不设置默认也是私有),也就无法实例化,会直接报错。重载时同理。

在unity中也可使用泛型gameObject.AddComponent<>(),另外使用泛型时,即使构造函数是私有也可以调用。不过使用泛型实例化不知如何传参,也就无法选择重载了。

  1. 构造函数还可以设置为静态的,使用关键字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 静态函数");
	}
    
	/*atic Exercise_4_9(int x)					// 报错,静态不能有参数
	{
	}*/
}
/* ... */
Exercise_4_9.num = 1;							// 调用一次静态构造函数,之后不会再调用
Exercise_4_9 myClass = new Exercise_4_9();		// 若没有上一行,这一行会先静态再普通
Exercise_4_9 myClass1 = new Exercise_4_9();		// 
  1. 构造函数在继承时不会被覆盖,子父类的构造函数都会存在并依次调用。(先父类后子类)
/* 续上一个例子中的 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();
    }
}
  1. 在微软手册中《构造函数 - C# 编程指南 | Microsoft Docs》,还提到,如果构造函数只有一句,则可以使用表达式主体定义

封装

参考《C# 封装 | 菜鸟教程 (runoob.com)》《C#中默认访问修饰符_给永远比拿愉快-CSDN博客》

  • C# 封装根据具体的需要,设置使用者的访问权限,并通过 访问修饰符 来实现。在类的继承中很重要的概念。

一个 访问修饰符 定义了一个类成员的范围和可见性。C# 支持的访问修饰符如下所示:

  • public:所有对象都可以访问;
  • private:对象本身在对象内部可以访问;
  • protected:只有该类对象及其子类对象可以访问
  • internal:同一个程序集的对象可以访问;
  • protected internal:访问限于当前程序集或派生自包含类的类型。
  • 具体例子结合下一个知识点——继承讲解。

继承

  • 继承是面向对象程序设计中最重要的概念之一
  • 和python的形式不一样,不需要括号,只需要冒号分隔。

在unity中:

  1. 每个挂载到游戏对象的脚本,都必须继承父类MonoBehaviour

  2. 有个常用操作,如果想往一个类中添加内容方法或属性,可以基于此类新定义一个派生类。然后其他类都继承此派生类即可。比如:类① 继承了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	// 父类已经继承 MonoBehaviour ,该类也相当于继承了
{
	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);			// public 直接继承父类,不用前缀即可访问。10
		// Debug.Log(num_1);		// private 不能外部访问,即使子类也不可。11
		Debug.Log(num_2);			// protected 限定子类。12
		get_s();					// 静态方法也是直接访问
		return num_01;				// 20
	}
	
	public void get_all()
	{
		Debug.Log(get_num_0());		// 函数同理。10
		// Debug.Log(get_num_1());	// 11
		Debug.Log(get_num_2());		// 12
	}
}

脚本③:(实例化)

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());	// public 公开
		// Debug.Log(myClass.get_num_11);	// private 不能外部
		// Debug.Log(myClass.get_num_12);	// protected 只能子类
        
        /* 更多打印调试不列举了 */
    }
}
  • 总结
  1. 基于访问修饰符,父类(含静态)的属性和方法可直接在子类中访问。不需要前缀,宛如就是在子类中定义似的。
  2. 子类继承父类的静态后,属于引用。本质上还是父类的静态,如果子类修改了父类的静态,父类会同步修改;反之亦然。

还有覆写等知识点,下一篇再写,发现太多了。

你可能感兴趣的:(#,unity,csharp,学习笔记,unity,c#,游戏引擎)