Unity学习笔记(五)

再谈访问修饰符

const

const关键字可以用来创建储存常量和不变值的变量,但常量变量只能在声明时赋值,不能没有初始值。

readonly

readonly关键词声明变量会使值与常量一样不可修改,但是可以在析构函数中随时分配其初始值。而且,由于引用类型包含对其数据的引用,因此作为引用类型的字段必须始终引用同一对象。该对象不是不可变的。修饰符可防止字段被引用类型的其他实例替换。

static

并非所有类都需要实例化,也不是所有属性都属于特点实例。使用static关键字创建的静态类是密封的,这意味着它们不能用于类继承。

再谈方法

方法重载

方法重载是指在一个类中创建多个名称相同但方法签名不同的方法,方法签名有由其名称和参数组成。C#编译器通过方法签名识别方法。我们可以保持方法名不变,通过更改参数数量或者类型来重载该方法。当为给定操作提供多种选择时,方法重载提供了额外的灵活性。

ref参数

默认情况下,所有参数都是通过值类型传递的,这意味着大多数情况下传递给方法的变量不会受到方法内对其值所做的任何更改的影响。而在声明参数时使用ref和out关键字可以将该参数标记为引用类型,通过引用的方式来传递参数。
对于ref关键字:

  • 参数必须在给方法之前进行初始化
  • 结束方法之前不需要对引用类型的参数值进行初始化或赋值
  • 带有get和set访问器的属性不能用作ref或out参数

out关键字作用与ref相同,但使用规则不同:

  • 参数传递给方法之前不需要初始化
  • 引用的参数在方法返回之前,必须在调用方法中初始化或赋值

使用out关键字更适合需要从多个函数中返回多个值的情况,而ref关键字在只需要修改引用值时效果最佳。

再谈面向对象

接口

接口是一种可以将功能聚集在一起的方法,与类相同,接口是数据和行为的蓝图,但它们有一个重要的区别:接口不能有任何实际的实现逻辑或储存,接口需要由结构体或类来填充自身定义的值和方法。接口的重要性在于:类和结构体都可以使用接口,并且,单个对象可以使用的接口数量没有限制。

public interface IManager
{
	string State{get;set;}
	void Initialize();
}
public class GameBehaviour:MonoBehavioer,IManager
{
	private string _state;
	public string State
	{
		get{return _state;}
		set{_state=value;}
	}
	void start()
	{
	Initialize();
	}
	public void Initialize()
	{
		_state="Mananger initialized";
		Debug.Log(_state);
	}
}

注意接口的所有属性都需要至少一个get访问器才能通过编译,根据需要,也可以同时拥有get和set访问器。

抽象类

另一种在对象之间实现分离并共享通用蓝图的方法是使用抽象类,与接口一样,抽象类中的方法不能包含任何实现逻辑,但是抽象类可以储存变量值。任何从抽象类派生出的子类都必须实现所有用abstarct标记的变量和方法。下面将前面的IManager接口和功能转换为抽象基类。

public abstract class BaseManager
{
	protected string _state;
	public abstract sring state{get;set;}
	public void Initialize();
}
public class CombatManager:BaseManager
{
	public override string state
	{
	get{return _state;}
	set{_state=value;}
	}
	public override void Initialize()
	{
		_state="Manager initialized..";
		Debug.Log(_state);
	}
}

类的扩展

通常,并不需要从头开始构建一个新类。有时,只需要将想要的功能或逻辑加到现有类中,这种方式称为类的扩展。类扩展背后的思想很简单:针对现有的C#内置类,按需添加任何希望它们具有的功能。

类的修改只能用方法来实现,不允许用变量或其他实体:

public static returnType MethodName(this ExtendingClass localVal);

扩展方法在声明时使用的方法与普通语法相同,但有几点需要注意。

  • 所有扩展方法标记为静态

  • 第一个参数必须用this关键字,后跟要扩展的类名和一个局部变量名

    • 这个特殊参数让编译器将方法识别为扩展,并为现有类提供本地引用
    • 通过这个局部变量访问任何类的方法和属性
    • 通常在静态类中存储扩展方法

下面来实践一下。
先创建一个脚本名为CustomExtensions并添加以下代码

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace CustomExtentions
{
    public static class StringExtentions
    {
        public static void FancyDebug(this string str)
        {
            Debug.LogFormat("This string contains {0} characters.",str.Length);
        }
    }
}

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using CustomExtentions;
public class NewBehaviourScript : MonoBehaviour
{
    // Start is called before the first frame update

    void Start()
    {
        string tstate = "custom";
        tstate.FancyDebug();
    }

    // Update is called once per frame
    void Update()
    {
        
    }
}

在这里插入图片描述
可知自定义方法成功。

再谈命名空间

随着应用程序越来越复杂,通常会将代码划分到不同的命名空间以随时随地地访问和控制代码。当两个及两个以上的类或者类型具有相同名称时就会发生命名空间冲突,幸运的是C#对这种情况提供了一种简单的解决方案:类型别名。
定义类型别名允许在给定的类中明确选择使用哪一种冲突类型,或者为现有类型创建一个更友好的名字。定义类型别名要使用using指令添加在类文件的顶部添加类型别名,后跟别名和分配类型:

using aliasName =type;

例如创建一个类型别名来引用现有的Int64类型:

using CustomInt = System.Int64;

(其实我感觉和typedef的用法差不多doge)

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值