目录
只要接触到了C#就一定听到过这句话“C#是面向对象的编程语言”,那么到底什么是面向对象的编程?
面向对象编程——OOP(Object-Oriented Programming),指的是在编程时将任何事物都看作一个对象来描述,正因如此,面向对象编程可读性更高,理解起来也更加容易,这就是为什么会说跟C++相比C#学起来会更加简单吧。
封装,被定义为把一个或多个项目封闭在一个物理的或者逻辑的包中“,隐藏对象的内部状态和功能的细节信息,提供一些公共元素进行访问。
还是用手机举例子:通过手机的一些按键就可以进行一些操作,但是我们不知道手机内部硬件是怎样实现这些操作的。封装可以让使用者不必关心对象是如何实现的,只须知道对象的用法。
抽象和封装通常被一起提及,实现封装后,提供的一些抽象的公共元素——类、方法等实现了信息的可视化,然而用户对这些信息的访问权限也不全是公开的。
C#封装利用访问修饰符来实现对使用者访问权限的设置,C#有以下访问修饰符
C#的继承主要体现在类之间的继承,通过继承我们可以根据一个类来定义另一个类,提高代码的重用性。例如以下代码中
- public class MyPlayer : MonoBehaviour
- {
- ...
- }
创建了一个新的类MyPlayer,它继承了Unity脚本API中的基础类MonoBehaviour,也就意味着继承了这个基础类的数据成员和成员函数,就不需要重复编写了。
这个关系中,MyPlayer称为派生类,MonoBehaviour称为基类。
可以举个例子,同一个项目中有很多类似的怪物,这是个时候需要一个Monster怪物基类。
(1)我们先分别创建了Phoenix和Dragon类
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
-
- namespace Assets.MyScript
- {
- [Serializable]
- public class Phoenix
- {
- public string name;
- public int age;
- public string furcolor;
- public int hp;
-
- //重生
- private bool respawn = false;
-
- //参数构造函数
- public Phoenix(string name, int age, string furcolor, int hp)
- {
- this.name = name;
- this.age = age;
- this.furcolor = furcolor;
- this.hp = hp;
- }
-
- void Respawn()
- {
- this.hp = 100;
- this.respawn = true;
- }
- }
- }
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- using UnityEngine;
-
- namespace Assets.MyScript
- {
- [Serializable]
- public class Dragon
- {
- //名字
- public string name;
- //年龄
- public int age;
- //血量
- public int hp;
-
- //全参的构造函数
- public Dragon(string name, int age, int hp)
- {
- this.name = name;
- this.age = age;
- this.hp = hp;
- }
- }
- }
可以发现,这两个类有一些共有属性,名字、年龄、血量等,像这样有用很多共同属性的类,可以创建一个基类来包括进去,这里我们创建一个Monster类。
(2)在Phoenix或Dragin的类名上 -> alt+enter打开提取基类 -> 选择包含的成员,点确定
这就获得了一个基类Monster——包含了name/age/hp以及一个空的构造函数的一个基类。
此时刚刚操作的Phoenix类就自动加上了Monster基类,Phoenix就成它的衍生类。
还需要更改一下构造函数部分,需要继承Monster的部分,并加入自己的新的成员
在Dragon类加上Monster并删除多余的。
基于刚刚创建的Monster基类创建一个派生类Tiger,并加入一个Blow构造函数。
查看结果
Debug结果:
同一个行为具有不同的表象形式,或者说以不同方式实现继承属性或者方法,这就叫做多态。在C#中通过类的继承或接口来体现多态这一特性。
简单了解一下什么是对象:对象包括属性和方法
假设我们有一个手机对象,那么手机的款式、型号等就是它的属性,而用手机打电话、发短信等操作就是它的方法。
C#中一切都与类和对象及其属性和方法有关,当你定义了一个类,就定义了一个数据类型的蓝图。举个例子:一个学生是一个“类”,而一位叫小明的学生,他就变成了一个“对象”了,类更像是一个概念,而对象则是将类实例化成了一个有具体信息的个体。
类的成员分为实例成员和静态成员。
静态成员——可以使用static关键字把类成员修饰成静态的。
当一个成员被声明为静态之后,无论有多少类的成员被创建,他们只会有一个该静态成员的副本。 静态变量用于定义类中的常量,无需创建实例可以直接调用类来获取,可在外部也可在内部定义。
C#中,所有类都派生子Object类,即使这个派生类没有任何的基类,也会把Object当作它的基类。
延续2.2中继承创建基类的程序文件,我们创建一个Monster类对象
再调用类中成员时,出现了Monster类中没有的成员项,例如Equals/ToString/GetType等,这些都是Object中封装的。
在使用类的静态方法或属性时,不需要将类实例化,除此之外所有C#中的类都必须实例化成对象后才能使用。
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
- using System;
-
- public class MyPlayer : MonoBehaviour
- {
- public string myName;
- public Cat cat;
- void Start()
- {
- cat.Print();
- }
- }
-
- [Serializable]
- public class Cat
- {
- //数据成员
- public string name;
- public int age;
-
- /*//构造函数
- public Cat(string name, int age)
- {
- this.name = name;
- this.age = age;
- }*/
-
- //成员方法
- public void Print()
- {
- Debug.Log($"这只小猫叫{name},它今年{age}岁了");
- }
- }
输入name和age后,ctrl+p的运行结果
在Unity中,我们都知道如果想要将某个定义的变量可视化,加上public即可,例如
但要想给脚本中定义的类对象可视化,仅加上public是不够的,还需要在定义那个类的前面加上
[Seralizable] 是在命名空间System下的
如此,该类创建出来的对象加上public就能可视化在属性窗口了。
文章结束了,只是作为类和对象的初始了解,之后会令开一贴记录C#在Unity中类使用的学习。