封装
封装 被定义为"把一个或多个项目封闭在一个物理的或者逻辑的包中"。在面向对象程序设计方法论中,封装是为了防止对实现细节的访问。
抽象和封装是面向对象程序设计的相关特性。抽象允许相关信息可视化,封装则使开发者实现所需级别的抽象。
C# 封装根据具体的需要,设置使用者的访问权限,并通过 访问修饰符 来实现。
访问修饰符
- private:私有的,类成员默认级别,仅在类内部可访问。
- internal:内部的,类默认级别(不需要写关键字),不管子类父类,只要在同一程序集(DLL、EXE)内就可见。
- protected:受保护的,不管是否同一个程序集,只要是本类或者派生类都可见。
- protected internal:内部或保护类可见,是protected或者internal的关系,只要满足一种条件就可见,等于是两种情况同时使用。
- public :公有的,类内类外均可见。
C#修饰符:
修饰符 | 当前类 | 同程序集 | 子孙类(同程序集) | 子孙类(不同程序集) | 其他程序集 |
---|---|---|---|---|---|
public | Y | Y | Y | Y | Y |
protected internal | Y | Y | Y | Y | N |
protected | Y | N | Y | Y | N |
internal | Y | Y | Y | N | N |
private | Y | N | N | N | N |
C#跟Java修饰符有区别吗?区别不大,但是还是有一些不同:
- Java中使用的是包的概念,而C#讲的是程序集。
- Java中的protected默认就是同包才可访问,而C#是不同程序集的子类也可访问protected。
- Java子类与基类在同一包中:被声明为 protected 的变量、方法和构造器能被同一个包中的任何其他类(不一定是子类)访问;
- Java子类与基类不在同一包中:那么在子类中,子类实例可以访问其从基类继承而来的 protected 方法,而不能访问基类实例的protected方法。(由于不是Java笔记,此处不过多赘述)
Java修饰符:
修饰符 | 当前类 | 同包 | 子孙类(同包) | 子孙类(不同包) | 其他程序集 |
---|---|---|---|---|---|
public | Y | Y | Y | Y | Y |
protected | Y | Y | Y | Y/N(见区别4) | N |
default | Y | Y | Y | N | N |
private | Y | N | N | N | N |
方法的定义
当定义一个方法时,从根本上说是在声明它的结构的元素。在 C# 中,定义方法的语法如下:
<Access Specifier> <Return Type> <Method Name>(Parameter List)
{
Method Body
}
下面是方法的各个元素:
- Access Specifier:访问修饰符,这个决定了变量或方法对于另一个类的可见性。
- Return type:返回类型,一个方法可以返回一个值。返回类型是方法返回的值的数据类型。如果方法不返回任何值,则返回类型为 void。
- Method name:方法名称,是一个唯一的标识符,且是大小写敏感的。它不能与类中声明的其他标识符相同。
- Parameter list:参数列表,使用圆括号括起来,该参数是用来传递和接收方法的数据。参数列表是指方法的参数类型、顺序和数量。参数是可选的,也就是说,一个方法可能不包含参数。
- Method body:方法主体,包含了完成任务所需的指令集。
形参与实参
形参出现在函数定义中,在整个函数体内都可以使用, 离开该函数则不能使用。
实参出现在主调函数中,进入被调函数后,实参变量也不能使用。
举例:
- 比如你定义一个函数 void add(int a, int b),这里的a和b就是形参。
- 当你进行函数调用的时候,add(1, 2),这里的1和2就是实参。
方法参数
方法的参数一共有八种情况:
- 值参数:普通的传参,形参随方法执行而废弃。
- 引用参数:定义参数和传参时在参数前面加个 ref(void fun(ref int a)),形参完全等同于实参,即使是数值型传入也只是传引用。引用参数的作用是为了强制改变参数值,引用参数容易造成数据混乱,不建议使用。
- 输出参数:定义参数和传参时在参数前面加个 out(void fun(out int a)),语法跟引用参数差不多,区别是方法内部必须给参数赋值,不能直接使用,也就是说进入方法前的值一定不会被使用。输出参数用于返回结果,可以一次返回多个结果,等于节省了一个包装类。
- 参数数组:跟Java的…类似,在参数前面加 params(void fun(params int[] a)),调用时可分别传参,也可直接给数组。
- 命名参数:调用方法时可以不按顺序传参,“形参名+冒号+实参”(obj.Sum(num2: 10, num1: 15, ram: 20)),程序会根据参数名匹配参数,而不是按照参数顺序。
- 可选参数:可不传参的参数,定义形参时赋值,调用时不传参,可单独使用,也可以结合命名参数使用,放在固定参数之后,params(参数数组)参数之前。void Sum(int num1 = 3, int num2 = 5, int num3 = 7),调用该方法时可以忽略已经赋值过的参数,如果有多个则按照顺序传值。
- 可为空参数:值类型(包含枚举、结构体)参数是不允许传null的, 只要在参数类型后面加一个问号 ?,就可以允许实参为null。例如定义方法时( void AddEntity(MyEntity? entity))就可以允许调用端传参时传null值。
- 扩展方法参数:在参数前面加 this,这个参数可以给该参数类型扩展一个方法,该类型的参数只能出现在静态类中,下面的章节将会对此进行详细讲解。
扩展方法参数
方法参数中有一个很特别的类型,这个类型能够将当前方法扩展给参数对应的类,我们可以直接从参数所对应的类对象中调用这个扩展的方法,这种参数就叫做扩展方法参数。
由于扩展方法参数很特别,几乎脱离了参数的范畴,所以不在本章中详细讲解,有兴趣的可以参考我的另外一篇文章【Unity】Unity开发进阶(七)双刃剑:扩展方法
更多内容请查看总目录【Unity】Unity学习笔记目录整理