02.class.md 10 KB

类和对象

所谓面向对象是指在编程时将任何事物都看成是一个对象来描述。

对象包括属性和方法,属性是指对象固有的特征,方法则是对象的行为。

面向对象语言的三大特征分别是封装、继承、多态。

类定义的具体语法形式如下。

类的访问修饰符    修饰符    类名
{
    类的成员
}

其中:

  • 类的访问修饰符:用于设定对类的访问限制,包括 public、internal 或者不写,用 internal 或者不写时代表只能在当前项目中访问类;public 则代表可以在任何项目中访问类。
  • 修饰符:修饰符是对类本身特点的描述,包括 abstract、sealed 和 static。abstract 是抽象的意思,使用它修饰符的类不能被实例化;sealed 修饰的类是密封类,不能 被继承;static 修饰的类是静态类,不能被实例化。
  • 类名:类名用于描述类的功能,因此在定义类名时最好是具有实际意义,这样方便用户理解类中描述的内容。在同一个命名空间下类名必须是唯一的。
  • 类的成员:在类中能定义的元素,主要包括字段、属性、方法。

访问修饰符

在 C# 语言中类定义后就要确定类中包含的内容,类中包含的内容被称为类中的成员。

类中的成员包括字段、属性、方法。每个类成员在定义时需要指定访问修饰符、修饰符。

类的访问修饰符主要有两个,即 internal 和 public,如果省略了访问修饰符,即为 internal。

  1. public 成员可以被任何代码访问。
  2. private 成员仅能被同一个类中的代码访问,如果在类成员前未使用任何访问修饰 符,则默认为 private。
  3. internal 成员仅能被同一个项目中的代码访问。
  4. protected 成员只能由类或派生类中的代码访问。

在修饰字段时通常用两个修饰符,即 readonly (只读)和 static (静态的)。

使用 readonly 修饰字段意味着只能读取该字段的值而不能给字段赋值。

使用 static 修饰的字段是静态字段,可以直接通过类名访问该字段。

需要注意的是常量不能使用 static 修饰符修饰。

访问修饰符    修饰符    数据类型    字段名;

方法的定义

方法是将完成同一功能的内容放到一起,方便书写和调用的一种方式,也体现了面向对象语言中封装的特性。

访问修饰符    修饰符    返回值类型    方法名(参数列表)
{
    语句块;
}

其中:

  1. 访问修饰符 所有类成员访问修饰符都可以使用,如果省略访问修饰符,默认是 private。
  2. 修饰符 在定义方法时修饰符包括 virtual(虚拟的)、abstract(抽象的)、override(重写的)、static(静态的)、sealed(密封的)。override 是在类之间继承时使用的。
  3. 返回值类型 用于在调用方法后得到返回结果,返回值可以是任意的数据类型,如果指定了返回值类型,必须使用 return 关键字返回一个与之类型匹配的值。如果没有指定返回值类型,必须使用 void 关键字表示没有返回值。
  4. 方法名 对方法所实现功能的描述。方法名的命名是以 Pascal 命名法为规范的。
    1. 参数列表 在方法中允许有 0 到多个参数,如果没有指定参数也要保留参数列表的小括号。参数的定义形式是“数据类型参数名”,如果使用多个参数,多个参数之间需要用逗号隔开。

get 和 set 访问器

属性经常与字段连用,并提供了 get 访问器和 set 访问器,分别用于获取或设置字段的值。

get 访问器和 set 访问器的使用与方法非常类似,可以在操作字段时根据一些规则和条件来设置或获取字段的值。

此外,为了保证字段的安全性,还能选择省去 get 访问器或 set 访问器。

public    数据类型    属性名
{
    get
    {
        获取属性的语句块;
        return 值;
    }
    set
    {
        设置属性得到语句块;
    }
}

其中:

  • get{} get 访问器,用于获取属性的值,需要在 get 语句最后使用 return 关键字返回一个与属性数据类型相兼容的值。

若在属性定义中省略了该访问器,则不能在其他类中获取私有类型的字段值,因此也称为只写属性。

  • set{} set 访问器用于设置字段的值,这里需要使用一个特殊的值 value,它就是给字段赋的值。

在 set 访问器省略后无法在其他类中给字段赋值,因此也称为只读属性。

调用类成员

调用类的成员实际上使用的是类的对象,对于创建类的对象,首先可以将类理解成一个模板,类的对象则是按照这个模板定制的一个对象。

创建类对象的语法 形式如下。

类名对象名 = new 类名();

上面的语法形式是一种简单形式,通过“对象名”即可调用类中的成员。调用的语法形式如下。

对象名 . 类的成员

给属性赋值的代码如下。

类的对象 . 属性名 = 值;

使用类的对象调用方法的代码如下。

类的对象 . 方法名(参数);

如果将类中的成员使用修饰符 static 声明,则在访问类成员时直接使用“类名.类成员”的方式即可。

构造函数(构造方法)

创建类的对象是使用“类名 对象名 = new 类名()”的方式来实现的。

实际上,“类名()”的形式调用的是类的构造方法,也就是说构造方法的名字是与类的名称相同的。

构造方法的定义语法形式如下。

访问修饰符 类名 (参数列表)
{
语句块;
}

这里构造方法的访问修饰符通常是 public 类型的,这样在其他类中都可以创建该类的对象。

如果将访问修饰符设置成 private 类型的,则无法创建该类的对象。构造方法中的参数与其他方法一样,都是 0 到多个参数。

此外,构造方法是在创建类的对象时被调用的。通常会将一些对类中成员初始化的操作放到构造方法中去完成。

析构函数

构造方法是在创建类的对象时执行的,而析构方法则是在垃圾回收、释放资源时使用的。

析构方法的定义语法形式如下。

~类名()
{
    语句块;
}

在析构方法中不带任何参数,它实际上是保证在程序中会调用垃圾回收方法 Finalize()。

方法重载(函数重载)

定义构造方法时提到可以定义带 0 到多个参数的构造方法,但构造方法的名称必须是类名。实际上,这就是一个典型的方法重载,即方法名称相同、参数列表不同。

参数列表不同主要体现在参数个数或参数的数据类型不同。在调用重载的方法时系统是根据所传 递参数的不同判断调用的是哪个方法。

方法的参数(实参和形参)

方法中的参数分为实际参数和形式参数,实际参数被称为实参,是在调用方法时传递的参数;形式参数被称为形参,是在方法定义中所写的参数。

方法中的参数除了定义数据类型外,还可以定义引用参数和输出参数。引用参数使用 ref 关键字定义,输出参数使用 out 关键字定义。

引用参数在方法中使用时必须为其值,并且必须是由变量赋予的值,不能是常量或表达式。

如果需要将方法中的每一个参数都设置为 ref 类型参数,则需要在每一个参数前面加上 ref 关键字修饰。

引用参数与我们平时使用的参数有些类似,但输出参数不同,输出参数相当于返回值,即在方法调用完成后可以将返回的结果存放到输出参数中。

输出参数多用于一个方法需要返回多个值的情况。需要注意的是,在使用输出参数时,必须在方法调用完成前为输出参数赋值。

在调用含有带输出参数的方法时,必须在传递参数时使用 out 关键字,但不必给输出参数赋值。

struct:结构体类型

结构体与类比较相似,由于它是值类型,在使用时会比使用类存取的速度更快,但灵活性方面没有类好。

结构体从字面上来理解是指定义一种结构,实际上结构体是一种与类的定义非常相似的数据类型,但它是值类型。

结构体的定义位置与枚举类型一样,都是在类中定义或者在命名空间下定义,而不能将其定义到方法中。

在结构体中能定义字段、属性、方法等成员。定义的语法形式如下。

访问修饰符  struct  结构体名称
{
    //结构体成员
}

其中:

  1. 访问修饰符 通常使用 public 或者省略不写,如果省略不写,代表使用 private 来修饰。 如果结构体中的内容要被其他类中的成员访问,需要将其访问修饰符设置为 public。
  2. 结构体名称 命名规则通常和变量的命名规则相同,即从第二个单词开始每个单词的首字母大写。
  3. 结构体成员 包括字段、属性、方法以及后面要介绍的事件等。

在结构体中也能编写构造器,但必须带参数,并且必须为结构体中的字段赋初值。

在调用结构体的成员时,能使用不带参数的构造器,与创建类的对象时类似。

结构体与类有些类似,但其定义却有很大区别,具体如下表所示

结构体
允许不使用 new 对其实例化 必须使用 new 实例化
没有默认构造方法 有默认构造方法
不能继承类 能继承类
没有析构方法 有析构方法
不允许使用 abstract、protected 以及 sealed 修饰 允许使用 abstract、protected 以及 sealed 修饰