Unity面向对象开发

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_24634505/article/details/80803314

视频教程:http://www.bilibili.com/video/av3246302/
https://www.bilibili.com/video/av6271851/
作者:风农

面向对象开发教程

属性
属性是比公共变量更好的访问类内部变量的方法。其本身类似于变量,在其内部封装了一些变量(域),封装可以更好的控制域被访问的过程。标准形式如下:

private int exp;
public int Exp
{
    get
    {
        return exp;
    }
    set
    {
        exp=value;
    }
}

    public int exp{get;set;}

这样做的好处是,可以通过不写get或set控制变量只读或只写,或在get和set函数中进行计算。

Static
静态成员和方法属于类本身,被所有类的实例所共享,可以通过类名直接访问。unity也有很多静态方法如Input.getAxis。
注意:静态方法中不能使用非静态变量。

静态类不能有实例,是一个完全由静态变量和函数组成的类。

泛型

    //泛型方法定义
    public T GenericMethod<T,U,V>(T param)where T:
    {
        return param;
    }
    //调用
    myClass.GenericMethod<int>(5);

可以在“where T:”后面加上对类型T的限定。

也可以声明泛型类,然后在类内部正常的使用类型T:

    //类定义
    public class GenericClass<T>
    {
        T item;
        public void UpdateItem(T i);
    }

    //初始化类对象
    GenericClass<int> myClass=new GenericClass<int>();
    myClass.UpdateItem(5);

泛型常应用于集合,如字典、列表等。

接口
接口是功能的一种约定,实现接口的类必须实现接口规定的所有函数和属性。
接口的好处在于可以跨越类型,定义常用的功能,并且根据接口大致知道这个类能做什么。并且类可以实现多个接口,但只能继承一个父类,实现接口比继承父类更加灵活。
这里写图片描述
接口没有自己的实例。

接口名通常是大写字母I开头的,经常以able结尾,如IDamageable。

扩展方法Extension Methods
用来给类型增加功能,而不用创建一个衍生类型或修改原类型,因此很适用于需要增加类功能,但不能修改类本身的情况。

拓展方法必须放在无泛型的静态类中。

    //定义
    public static class ExtensionMethods
    {
        public static void ResetTransformation(this Transform trans)
        {

        }
    }

第一个参数要用this关键字修饰,这个参数指明了方法会成为哪个类的一部分,调用函数的时参数隐含的变成transform的实例,不需要再提供。后面的参数就不再需要this关键字了。
现在这个方法已经视为transform类的一部分。

    //调用
    transform.ResetTransformation();//直接使用就好,也不用传参。

命名空间
主要目的是作为类的容器帮助整理脚本,避免脚本间冲突。

列表和字典Lists&Dictionaries
list是动态大小的数组,可以像数组一样访问。(System.Colletions.Generic)
对于实现了IComparable接口的类,list还可以用sort函数进行排序。

字典是存储键值对的数据结构,其主要目的是查询。注意:如果键不存在会抛出异常,因此如果不确定是否会抛出异常就使用TryGetValue函数,如:

    if(guys.TryGetValue("birds",out temp))//不过这样做性能差一点
    {
    }

协程Coroutine
是间隔调用的函数,用yield声明将代码执行流程跳到函数外,yield的返回值控制何时恢复协同程序从刚刚的位置继续向下执行。

    //定义
    IEnumerator MyCoroutine(Transform target)
    {
        while(Vector3.Distance(transform.position,target.position)>0.05f)
        {
            transform.position=Vector3.Lerp(transform.position,target.position,smoothing*Time.DeltaTime);
            yield return null;
        }
        print("reached");
        yield return new WaitForSeconds(3f);
        print("myRoutine now finished");
    }
    //调用
    StartCoroutine(MyCoroutine(target));

委托Delegate
可以简单的视为函数的容器,可以像变量一样传递和赋值函数。

在delegate脚本中,首先定义一个模板,模板定义了什么类型的函数可以赋值到委托中。如玩家受伤、攻击等事件发生时就可以广播给所有订阅了事件的函数知道。注意不用了之后取消订阅非常重要,否则会造成内存泄漏和一些错误。

    delegate void MyDelegate(int num);
    MyDelegate myDelegate;

    void Start()
    {
        myDelegate=PrintNum;//将函数赋值给delegate,然后像函数一样使用delegate
        myDelegate(50);

        myDelegate=DoubleNum;
        myDelegate(50);

        myDelegate+=PrintNum;//一个delegate可以包含多个函数
        myDelegate-=PrintNum;//从delegate中除去一个函数
    }

    void PrintNum(int num)
    {
    }

    void DoubleNum(int num)
    {
    }

属性Attributes
可以在声明时对函数、变量或类添加额外信息。
如:

    [Range(0,100)]//限定某个变量的范围
    public int speed=0;

事件Events
是一种特殊的委托。可以视为一个健壮灵活的广播系统,任何对事件感兴趣的类都可以向事件订阅,以在事件发生时调用注册的函数。广播系统本身对注册函数完全不了解,注册函数之间也完全不了解,只需关注触发事件。
注意:写订阅的时候要注意在对象销毁的时候注销订阅。


猜你喜欢

转载自blog.csdn.net/qq_24634505/article/details/80803314