`
longerdewo
  • 浏览: 29955 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

unity3d 重用,继承,泛型等使用

 
阅读更多

链接地址:http://blog.csdn.net/huang9012/article/details/38491943

如果创建新的类时,使用的是在unity editor的project视图中右键,create javascript or c#方式,那么创建的类都是默认继承自MonoBehaviour, 生成后可以查看类文件,会发现c#类继承自MonoBehaviour, 虽然javascript的类前面没有这个继承自MonoBehaviour的关键字样,但是默认也是从它继承而来,这是unity的规定。
这样的类和普通没有继承自MonoBehaviour的类,有什么区别呢?区别很多,我们只说一点: 继承自MonoBehaviour的类,不需要自己创建它的实例,也不能自己创建(如 new 类名),编译的时候可以编译过去,但是执行的时候会给你一个错误在unity editor的console窗口,并且你new 后得到的东西为空;其实这是unity的一个bug,既然继承自MonoBehaviour的类不能new出来,为什么在编译的时候就给个错误,而是在运行时,如果没有看到unity editor的console窗口的内容真的很难知道为什么new的东西为空。
为什么不需要自己创建呢?因为所有从MonoBehaviour继承过来的类,unity都会自动创建实例,并且调用被重载的方法,如我们经常用到的Awake, Start, Update等。

而普通类,就可以用new来创建实例了。

 

 

 在Unity脚本中使用继承和普通的C#没有多大区别,只要在父类只继承了MonoBehaviour就可以了,如果你将子类脚本贴到GameObject上,子类中如果有Awake,Start,Update等方法,将会覆盖父类中的这些方法,如果要掉用父类中的这些方法,可以使用base.Satrt(),base.Update().

 

 

 

使用泛型最大的好处就是代码复用,比如写一段程序要统计"水"的一些属性(信息),如这是什么样的水(矿泉水/自来水/污水.etc),或者水的温度是多少.可以这样写(使用结构体):

 

[csharp] view
plain
copy

 

 
  1. public class NewBehaviourScript : MonoBehaviour  
  2. {  
  3.     // Use this for initialization  
  4.     void Start()  
  5.     {  
  6.         Water test = new Water();  
  7.         test.name = "KuangQuanShui";  
  8.         test.temperature = 100;  
  9.         Debug.Log("水的名字: " + test.name + "   水的温度: " + test.temperature);  
  10.     }  
  11. }  
  12. public struct Water  
  13. {  
  14.     public string name;//水的名字  
  15.     public int temperature;//水的温度  
  16. }  

下面是使用泛型来重写上面的这段代码,如下:

 

[csharp] view
plain
copy

 

 
  1. public class fanxing : MonoBehaviour  
  2. {  
  3.     // Use this for initialization  
  4.     void Start()  
  5.     {  
  6.         Water<string> test1 = new Water<string>();  
  7.         test1.info = "KuangQuanShui";//在此传入水的名字是"矿泉水"(可以将"T"看作是string类型)  
  8.   
  9.         Water<int> test2 = new Water<int>();  
  10.         test2.info = 100;//在此传入水的温度是 100(可以将"T"看作是int类型)  
  11.         Debug.Log("水的名字: " + test1.info + "   水的温度: " + test2.info);  
  12.     }  
  13. }  
  14. public class Water<T>  
  15. {  
  16.     public T info;//水的信息(属性)  
  17. }  

上面的"T"可以看作是任意数据类型,(对于为何不使用基类型object及涉及的装箱/拆箱,网上介绍的很详细了,在这就不过多叙述了)通过上面的两段代码可能还看不出泛型有多大的好处,但是想想如果是使用泛型来初始化单例,是不是方便很多.

对于泛型的约束:如果我只允许"T"接收某一个数据类型(比如自定义了一个构造函数,只接收这个类型)如下:

 

[csharp] view
plain
copy

 

 
  1. public class fanxing : MonoBehaviour  
  2. {  
  3.     // Use this for initialization  
  4.     void Start()  
  5.     {  
  6.         WaterBase waterInfo = new WaterBase();  
  7.         Water<WaterBase> test3 = new Water<WaterBase>();//Water<限定只能为WaterBase类型>  可以将"T"看作是WaterBase类型  
  8.         test3.info = waterInfo;  
  9.         test3.info.name = "KuangQuanShui";  
  10.         test3.info.temperature = 100;  
  11.         Debug.Log("水的名字是: " + test3.info.name + "   水的温度是: " + test3.info.temperature);  
  12.     }  
  13. }  
  14. public class Water<T> where T : WaterBase  
  15. {  
  16.     public T info;//水的信息(属性) 可看作"T"的类型是WaterBase  
  17. }  
  18. public class WaterBase  
  19. {  
  20.     public string name;  
  21.     public int temperature;  
  22. }  

泛型的约束,官网规定如下:

如果是多个占位符的泛型(两个),示例代码如下:

 

[csharp] view
plain
copy

 

 
  1. public class fanxing : MonoBehaviour  
  2. {  
  3.     // Use this for initialization  
  4.     void Start()  
  5.     {  
  6.         //从A产线出来的生产日期是string类型的"20130610",水是矿泉水,温度是20,  
  7.         Water<string, WaterBase> test1 = new Water<string, WaterBase>();//Water<任意类型,直接收WaterBase类型> 在此"T"相当于string类型  
  8.         test1.data = "20130610";  
  9.         test1.info.name = "KuangQuanShui";  
  10.         test1.info.temperature = 20;  
  11.         //从B产线出来的生产日期是int类型的20130610,水是纯净水,温度是20,  
  12.         Water<int, WaterBase> test2 = new Water<int, WaterBase>();//Water<任意类型,直接收WaterBase类型> 在此"T"相当于int类型  
  13.         test2.data = 20130610;  
  14.         test2.info.name = "ChunJingShui";  
  15.         test2.info.temperature = 20;  
  16.     }  
  17. }  
  18. public class Water<T, U> where U : WaterBase //限定"U"只能接收WaterBase类型  
  19. {  
  20.     public T data;//出厂日期(可接受int型的20130610,或者string类型的"20130610");  
  21.     public U info;//水的具体信息(矿泉水/纯净水...温度)  
  22. }  
  23. public class WaterBase  
  24. {  
  25.     public string name;  
  26.     public int temperature;  
  27. }  

接下来是泛型的继承,下面分别是一个占位符/多个占位符的继承示例,以及泛型继承的写法:

 

[csharp] view
plain
copy

 

 
    1. public class fanxing : MonoBehaviour  
    2. {  
    3.     // Use this for initialization  
    4.     void Start()  
    5.     {  
    6.         TestChild1 test = new TestChild1();  
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics