C#系统学习第九章——面向对象编程基础

前言

在 C# 的编程宇宙里,面向对象编程(OOP)如同搭建数字大厦的基石 ------ 它用 "类" 与 "对象" 的概念,将现实世界的事物抽象为代码中的实体,以封装、继承、多态三大特性为工具,让程序不再是零散的指令堆砌,而是具有逻辑结构与复用能力的有机整体。


9.1 认识面向对象

面向对象的对象通常是指客观世界中存在的对象。

9.1.1 对象

对象是事物存在的实体。

对象主要是由两个部分组成,即静态部分与动态部分。

静态部分:属性。

动态部分:行为。

9.1.2 类

类就是同一类事物的统称。类是封装对象属性和行为的载体,而具有相同属性和行为的一类实体被称为类。

9.1.3 面向对象技术的基本思想


现实世界-->由具体对象抽象出类-->面向对象建模(类、对象、方法)-->程序实现-->执行求解


9.1.4 面向对象程序设计的特点

1.封装

封装是面向对象编程的核心思想。将对象的属性和行为封装起来就是类。

封装好处:保证了类内部数据结构的完整性,使用该类的用户不能直接看到类中的数据结构,也无需知道类中的具体细节,只需要执行类允许公开的数据,避免了外部对内部数据的影响,提高了程序的可维护性。

面向对象程序设计采用封装具有两方面的含义:

(1)将有关的数据和操作代码封装在一个类中,各类之间相对独立,互不干扰。

(2)将类中的某些数据与操作代码对外隐蔽,即隐蔽实现其内部细节,只留下少量接口,以便与外部联系,接受外部消息。

2.继承

继承主要是利用特定对象之间的共有属性。在C#中可以说子类的对象都是父类的对象,但不能说父类的对象是子类的对象。

如果一个类处于继承体系中,那么他既可以是其他类的父类,也可以是其他类的子类。

如果类之间具有继承关系,则它们之间存在一下特性:

(1)类之间具有共享特性(包含属性和行为的共享)。

(2)类之间具有差别或新增部分(包含非共享的数据和程序代码)。

(3)类之间具有层次结构。

3.多态

将父类的对象应用于子类的特征就是多态。父类衍生出不同的子类,子类继承父类特征的同时,也具备了自己的特征,并且能够实现不同的效果,这就是多态化的结构。

多态的意义:同一操作作用于不同对象时,可以有不同的解释,从而产生不同的执行结果,即"以父类的身份出现,以自己的方式工作"。

9.1.5了解面向过程编程

主要思想:先做什么,后做什么,在一个过程中实现特定功能。

特点:

(1)重用性差

重用性指同一事物不经修改或稍加修改就可多次重复使用的性质。

(2)可维护性差

维护成本高。

(3)稳定性差

当用户需求发生变化时,就要修改最底层的结构。当处理的用户需求变化较大时,面向过程编程将无法修改,可能会导致软件的重新开发。


9.2 类

9.2.1 类的声明

在C#中,类是使用 class 关键字来声明的。

语法:

cs 复制代码
class 类名
{

}

9.2.2 类的成员

类的定义包括 类头 和 类体。

类头:类名。

类体:大括号以及包含内容。

1.字段

字段就是程序设计中常见的常量或者变量。

字段属于类级别的变量,未初始化,C#会将其初始化为默认值,但不会将局部变量初始化为默认值。

2.属性

属性是对实体特征的抽象,用于提供对类或对象的访问。C#中属性具有访问器,这些访问器指定在它们的值被读取或写入时需要执行的语句,因此属性提供了一种机制,用于把读取和写入对象的某些特征与一些操作关联起来。

cs 复制代码
【访问修饰符】 【类型】 【属性名】
{
    get {get 访问器体}
    set {set 访问器体}
}

访问修饰符:属性的访问级别(private public等等)

类型:指定属性的类型,可以是任何预定义或者自定义类型。

属性名:标识符,命名规则与变量相同,通常第一个字母大写。

get访问器:相当于一个具有属性类型返回值的无参数方法。

set访问器:相当于一个具有单个属性类型值参数和void返回类型的方法;set访问器的隐式参数始终命名为value;当一个属性作为赋值的目标被引用时,就会调用set访问器,所传递的参数将提供新值。

根据是否有get和set分为:

(1)可读可写属性:包含get和set访问器。

(2)只读属性:只包含get访问器。

(3)只写属性:只包含set访问器。

说明:属性的主要作用是限制外部类对类中成员的访问权限,定义在类级别上。

3.枚举

枚举是一种独特的字段,是值类型数据,主要用于声明一组具有相同性质的常量。

C#中使用关键字enum类声明枚举

cs 复制代码
enum 枚举名
{
    list1=value1,
    list2=value2,
    list3=value3,
    ......
    listn=valuen,
}

说明:在定义枚举时,如果不对其进行赋值,在默认情况下,第一个枚举数的值为0,后面每个枚举数的值依次递增1。

9.2.3 访问修饰符

注意:

(1)在定义类时,只能使用public 或者 internal,这取决于是否希望在包含类的程序外部访问它。

(2)如果有内部类,那么内部类总是可以访问外部类的所有成员。

9.2.4 构造函数

构造函数是一个特殊函数,它是在创建对象时执行的方法。构造函数具有与类相同的名称,通常用来初始化对象的数据成员。构造函数特点:

(1)构造函数没有返回值。

(2)构造函数的名称要与本类的名称相同。

1.构造函数定义

cs 复制代码
public class className
{
    public className()//无参构造函数
    {
    }
    
    public className(int args)//有参构造函数
    {
    }

public:访问修饰符。

className:类名。

args:构造函数的参数。

2.默认构造函数和有参构造函数

定义类时,如果没有定义构造函数,则编译器会自动创建一个不带参数的默认构造函数。

如果再定义类时定义了含有参数的构造函数,这时如果还想要使用默认构造函数,就需要显式进行定义。

3.私有构造函数

定义构造函数时,也可以使用private进行修饰,用于表示构造函数只能在本类中访问,其他类不能访问。

如果类中定义了私有构造函数,将导致类不能是使用new运算符在外部代码中实例化。可以通过编写一个公归公的静态属性或者方法来解决这个问题。

4.静态构造函数

这种构造函数只执行一次。编写静态构造函数的主要原因是类有一些静态字段或者属性,需要在第一次使用类之间从外部源中初始化这些静态字段和属性。

(1)定义静态构造函数,不能设置访问修饰符。

(2)不能带任何参数且一个类中只能有一个静态构造函数

(3)静态构造函数和实例构造函数可以共存。

9.2.5 析构函数

主要用来释放对象资源,Net Framework类库有垃圾回收功能。

语法:

cs 复制代码
~Program()
{
    console.write("析构函数调用");
}

说明:严格来说,析构函数是自动调用的,不需要开发人员显示定义。一般来说对象的生命周期从构造函数开始,以析构函数结束。


9.3 方法

方便代码的重复利用。

9.3.1 方法的声明

cs 复制代码
【访问修饰符】 返回值类型 方法名(参数列表)
{
    //方法的具体实现
}

(1)访问修饰符:private,public,protected,internal,也可以省略。

(2)省略的话,默认为private,即只能在类中访问。

9.3.2 方法的参数

调用方法时,需要向方法传递数据,这个数据就是参数。

形参和实参的概念:

在调用方法时可以给该方法传递一个或者多个值,传给方法的值叫做实参。

在方法内部,接收实参的变量叫做形参。形参只有在方法内部有效。

1.值参数

值参数就是在声明时不加修饰符的参数,它表明实参与形参之间按照值类型传递,即在方法中对值类型的形参修改不影响实参。

2.ref参数

ref参数使形参按引用传递(即使形参是值类型),其效果是在方法中对形参所做的任何修改都将反应在实参中。如果要使用ref参数,则方法声明和方法调用都必须显示调用ref关键字。

使用注意事项:

(1)ref关键字只对跟在他后面的参数有效,而不是应用于整个参数列表。

(2)在调用方法时,必须使用ref修饰实参;而且因为是引用参数,所以实参和形参的数据类型必须完全匹配。

(3)实参只能是变量,不能是常量或者是表达式。

(4)在调用ref参数之前,一定要进行赋值。

3.out参数

用来定义输出参数,它会使参数通过引用来传递,这与ref关键字类似。不同之处是 out关键字定义的参数不用进行复制即可使用。

4.params参数

适用条件:

(1)一个方法中有多个相同类型的参数

(2)方法中参数个数不固定

可以修饰一个一维数组,用来指定在参数类型相同,但数量过多或者不确定时所采用的方法参数。

使用注意事项:

(1)只能在一维数组中使用params参数。

(2)不允许使用ref眼见子或者out关键字来修饰该参数。

(3)一个方法最多只能有一个params参数。

9.3.3 重载方法

重载方法指 方法名相同,但参数的数据类型、个数或顺序不同的方法。

注意:

(1)重载方法不能仅是返回值类型不同。

(2)重载方法不能仅根据参数是否声明为ref、out或者params参数来区分。


9.4 类的静态成员

在C#中,共享的变量或者方法用static修饰,他们被称为静态变量和静态方法。也被称为类的静态成员。静态成员是属于类所有的,在调用时不用创建类的对象,可以直接使用类名调用。

注意:

(1)静态类中只能定义静态成员,不能定义实例变量,实例方法等。

(2)static不能修饰常量。


9.5 对象的创建及使用

9.5.1 对象的创建

在C#中,使用new关键字来创建对象。

语法:

cs 复制代码
Test test=new Test();
Test test=new Test("a");

test对象被创建时,就是一个对象的引用,这个引用在内存中为对象分配了内存空间

9.5.2 访问对象的属性和行为

语法:

对象.类成员名

9.5.3 对象的销毁

每个对象都有生命周期,当对象的生命周期结束后,分配给该对象的内存空间将会被回收。

以下两种情况的对象会被视为垃圾:

(1)如果对象引用超过其作用范围。

(2)将对象设为NULL。

9.5.4 this关键字

this关键字代表本类对象的引用。

9.5.5 类与对象的关系

类是一种抽象的数据类型,而对象是类的一个实例。

类是具有相同或相似结构,操作和约束规则的对象组成的集合,而对象是某一类的具体化实例,每一个类都是具有某些共同特征的对象的抽象。


结语

当你掌握了类与对象的设计原则,便如同获得了一把钥匙,能够打开复杂系统开发的大门 ------ 无论是企业级应用的架构设计,还是移动端 App 的功能实现,面向对象的思想都将助你以更清晰的逻辑组织代码,以更高的效率应对需求变化。愿这段关于 OOP 的探索,能让你在 C# 编程之路上迈出更坚实的一步。