目录
1 面向对象编程的概念
只要接触到了C#就一定听到过这句话“C#是面向对象的编程语言”,那么到底什么是面向对象的编程?
面向对象编程——OOP(Object-Oriented Programming),指的是在编程时将任何事物都看作一个对象来描述,正因如此,面向对象编程可读性更高,理解起来也更加容易,这就是为什么会说跟C++相比C#学起来会更加简单吧。
2 C#面向对象的三大特性
2.1 封装
封装,被定义为把一个或多个项目封闭在一个物理的或者逻辑的包中“,隐藏对象的内部状态和功能的细节信息,提供一些公共元素进行访问。
还是用手机举例子:通过手机的一些按键就可以进行一些操作,但是我们不知道手机内部硬件是怎样实现这些操作的。封装可以让使用者不必关心对象是如何实现的,只须知道对象的用法。
抽象和封装通常被一起提及,实现封装后,提供的一些抽象的公共元素——类、方法等实现了信息的可视化,然而用户对这些信息的访问权限也不全是公开的。
访问修饰符
C#封装利用访问修饰符来实现对使用者访问权限的设置,C#有以下访问修饰符
- public:公有的,类的成员可以从类外的任何位置被访问
- private:只能在自己的类体中可以被访问
- protected:只有该类对象及其子对象可以访问
- internal——同一程序集的对象可以访问
- prtected internal——本类、派生类或包含该类的程序集可访问
C#中默认访问修饰符
- 如果没有显示的给这些元素(类、接口、结构、枚举等)访问修饰符,默认为internal
- 类中所有成员默认均为private
- 接口的成员默认的是public
- 命名空间,枚举类型成员默认是public
2.2 继承
C#的继承主要体现在类之间的继承,通过继承我们可以根据一个类来定义另一个类,提高代码的重用性。例如以下代码中
public class MyPlayer : MonoBehaviour
{
...
}
创建了一个新的类MyPlayer,它继承了Unity脚本API中的基础类MonoBehaviour,也就意味着继承了这个基础类的数据成员和成员函数,就不需要重复编写了。
这个关系中,MyPlayer称为派生类,MonoBehaviour称为基类。
尝试根据已知类创建基类
可以举个例子,同一个项目中有很多类似的怪物,这是个时候需要一个Monster怪物基类。
(1)我们先分别创建了Phoenix和Dragon类
- Phoenix
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;
}
}
}
- Dragin
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结果:
2.3 多态
同一个行为具有不同的表象形式,或者说以不同方式实现继承属性或者方法,这就叫做多态。在C#中通过类的继承或接口来体现多态这一特性。
3 对象
简单了解一下什么是对象:对象包括属性和方法
- 属性——对象的固有特性
- 方法——对象的行为方法
假设我们有一个手机对象,那么手机的款式、型号等就是它的属性,而用手机打电话、发短信等操作就是它的方法。
4 类
C#中一切都与类和对象及其属性和方法有关,当你定义了一个类,就定义了一个数据类型的蓝图。举个例子:一个学生是一个“类”,而一位叫小明的学生,他就变成了一个“对象”了,类更像是一个概念,而对象则是将类实例化成了一个有具体信息的个体。
4.1 类的静态成员
类的成员分为实例成员和静态成员。
静态成员——可以使用static关键字把类成员修饰成静态的。
当一个成员被声明为静态之后,无论有多少类的成员被创建,他们只会有一个该静态成员的副本。 静态变量用于定义类中的常量,无需创建实例可以直接调用类来获取,可在外部也可在内部定义。
4.2 所有类都派生自Object类
C#中,所有类都派生子Object类,即使这个派生类没有任何的基类,也会把Object当作它的基类。
举例证明
延续2.2中继承创建基类的程序文件,我们创建一个Monster类对象
再调用类中成员时,出现了Monster类中没有的成员项,例如Equals/ToString/GetType等,这些都是Object中封装的。
4.3 C#中的基类一些规范
- 任何类只能有一个基类
- 子类代码里使用base关键字指代基类
- 构造方法较为特殊,有自己的名字,派生类中的构造方法不能继承自基类,需要重写
5 类&Unity组件
在使用类的静态方法或属性时,不需要将类实例化,除此之外所有C#中的类都必须实例化成对象后才能使用。
5.1 类在Unity的使用
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的运行结果
5.2 类对象在属性窗口的可视化
在Unity中,我们都知道如果想要将某个定义的变量可视化,加上public即可,例如
但要想给脚本中定义的类对象可视化,仅加上public是不够的,还需要在定义那个类的前面加上
[Seralizable] 是在命名空间System下的
如此,该类创建出来的对象加上public就能可视化在属性窗口了。
文章结束了,只是作为类和对象的初始了解,之后会令开一贴记录C#在Unity中类使用的学习。