CH08_类和对象


本章目标

  • 掌握类和对象
  • 理解封装
  • 会创建和使用对象

面向对象

面向对象的编程(Object-OrientedProgramming, OOP)语言己经在编程语言中占据了半壁江山,所谓面向对象是指在编程时将任何事物都看成是一个对象来描述。

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

例如将手机看作是一个对象,手机的大小、颜色、品牌都可以看作是一个特征,即属性,而打电话、发短信、上网是手机的行为,即方法。

面向过程的编程是把一个操作从头到尾写在一起,编程过程简单但缺乏可重用性,不方便软件的移植。

面向对象编程则是对传统的面向过程编程的一种颠覆,让编程看起来更容易理解,同时也增强了代码的重用性。

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

封装

封装就好像把所有的硬件设施放到手机里,而用户只能看到手机的外观,看不到手机内部的结构和硬件配置。

在 C# 语言中能体现封装特性的编程元素有很多,例如类、接口、方法等。

封装的好处就是能让用户只关心对象的用法而不用关心对象的实现,在为用户的访问提供了便利的同时也提高了程序的安全性。

继承

在 C# 语言中继承关系主要体现在类之间的继承,这样既能减少开发时的代码量又方便了程序的复用。

多态

在 C# 语言中多态是通过类的继承或接口的实现来体现的,多态给程序带来的最大好处与继承类似,即提高了程序的复用性和可移植性。

类的定义

语法

1
2
3
4
类的访问修饰符    修饰符    类名
{
类的成员
}

特点

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

案例1:新建一个类

1
2
3
4
5
6
7
8
9
10
11
12
13
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace FirstProject
{
class Test1
{
}
}

案例2: 在同一个命名空间中也可以定义多个类.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace FirstProject
{
class Test1
{

}

class Test2
{

}
}

尽管可以在一个命名空间中定义多个类,但不建议使用这种方式,最好是每一个文件定义一个类,这样方便阅读和查找。

字段的定义

语法

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

在这里访问修饰符和修饰符都是可以省略的,并且访问修饰符和修饰符的位置也可以互换,但从编码习惯上来说通常将访问修饰符放到修饰符的前面。此外,在类中定义字段时字段名是唯一的。

案例3:分别定义不同修饰符的字段。

1
2
3
4
5
6
7
class Test1
{
private int id; //定义私有的整型字段 id
public readonly string name; //定义公有的只读字符串类型字段 name
internal static int age; //定义内部的静态的整型字段 age
private const string major = "计算机"; //定义私有的字符串类型常量 major
}

通过上面的语句演示了不同修饰符字段的定义,重点是记住这些修饰符的使用。

字段在类中定义完成后,在类加载时,会自动为字段赋值,不同数据类型的字段默认值不同, 如下表所示。

特点

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

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

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

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

方法的定义

语法

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

特点

1.访问修饰符

​ 所有类成员访问修饰符都可以使用,如果省略访问修饰符,默认是 private。

2.修饰符

​ 在定义方法时修饰符包括 virtual(虚拟的)、abstract(抽象的)、override(重写的)、static(静态的)、sealed(密封的)。override 是在类之间继承时使用的。

3.返回值类型

​ 用于在调用方法后得到返回结果,返回值可以是任意的数据类型,如果指定了返回值类型,必须使用 return 关键字返回一个与之类型匹配的值。如果没有指定返回值类型,必须使用 void 关键字表示没有返回值。

4.方法名

​ 对方法所实现功能的描述。方法名的命名是以 Pascal 命名法为规范的。

5.参数列表

​ 在方法中允许有 0 到多个参数,如果没有指定参数也要保留参数列表的小括号。参数的定义形式是“数据类型参数名”,如果使用多个参数,多个参数之间需要用逗号隔开。

案例4: 在 Test 类中定义一个方法输出指定字段的值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Test
{
private int id; //定义私有的整型字段 id
public readonly string name; //定义公有的只读字符串类型字段 name
internal static int age; //定义内部的静态的整型字段 age
private const string major = "计算机"; //定义私有的字符串类型常量 major

private void PrintMsg()
{
Console.WriteLine("编号:" + id);
Console.WriteLine("姓名:" + name);
Console.WriteLine("年龄:" + age);
Console.WriteLine("专业:" + major);
}
}

案例5: 创建 Compute 类,分别定义 4 个方法实现加法、减法、乘法、除法的操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class Compute
{
//加法
private double Add(double num1,double num2)
{
return num1 + num2;
}
//减法
private double Minus(double num1,double num2)
{
return num1 - num2;
}
//乘法
private double Multiply(double num1,double num2)
{
return num1 * num2;
}
//除法
private double Divide(double num1,double num2)
{
return num1 / num2;
}
}

构造函数的定义

创建类的对象是使用“类名 对象名 = new 类名()”的方式来实现的。 实际上,“类名()”的形式调用的是类的构造方法,也就是说构造方法的名字是与类的名称相同的。

语法

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

特点

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

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

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

案例6: 创建用户类 User,并创建构造方法为用户类中的属性赋值。在 Main 方法中 调用输出用户信息的方法,用户属性包括用户名、密码、手机号。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class User
{
public User(string name, string password, string tel)
{
this.Name = name;
this.Password = password;
this.Tel = tel;
}
public string Name { get; set; }
public string Password { get; set; }
public string Tel { get; set; }

public void PrintMsg()
{
Console.WriteLine("用户名:" + this.Name);
Console.WriteLine("密 码:" + this.Password);
Console.WriteLine("手机号:" + this.Tel);
}
}

​ 在上面程序的构造方法中含有 3 个参数,为每一个属性赋值。这里用“this.属性名”的方式调用属性,this关键字表示当前类的对象。

1
2
3
4
5
6
7
8
9
class Program
{
static void Main(string[] args)
{
User user = new User("小明","123456","13131351111");
user.PrintMsg();
}
}

访问修饰符、修饰符

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

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

类中成员的访问修饰符有 4 个,具体用法如下。

1.public

​ 成员可以被任何代码访问。

2.private

​ 成员仅能被同一个类中的代码访问,如果在类成员前未使用任何访问修饰 符,则默认为private。

3.internal

​ 成员仅能被同一个项目中的代码访问。

4.protected

​ 成员只能由类或派生类中的代码访问。派生类是在继承中涉及的,将在后面详细介绍。

修饰字段时通常用两个修饰符

1.readonly (只读)

​ 只能读取,不能写入。

2.static (静态的)

​ 属性类而不属于对象,访问时要用类名访问。

课后作业

1.定义账户类Account,包含有账号、密码、存款金额等属性;定义管理员类Manager,包含Account属性,存款、取款等方法;定义测试类Test完成存款取款测试。