面向对象编程中的封装
人们经常混淆抽象和封装。正如我们在前一章中学到的,抽象是一种思维方式,而封装是实现抽象的一种技术。
封装是实现代码抽象的一种技术。通过适当的访问修饰符创建类及其成员,以显示或隐藏细节和复杂性。
封装隐藏了数据和实现细节,只显示类中必需的成员,从而隐藏了其他代码的复杂性。其他代码无需了解实现细节,也无法修改类的数据和方法的代码。
大多数面向对象编程语言允许您创建类及其属性和方法,并使用访问修饰符,例如 public、private、protected 和 internal,以显示或隐藏数据成员和实现细节。接口和抽象类也可以用于封装。
例如,Student 类包含以下成员

如您所见,FirstName
、MiddleName
、LastName
和 FullName
是数据成员,而 Save()
、Subscribe()
、GetSubscribedCourses()
是方法。
在 C# 中,我们主要使用类、接口、抽象类、属性、方法、结构、枚举和访问修饰符来实现封装。对于上述 Student
实体,我们可以创建 Student
类。将属性用于数据成员,将方法用于操作。
以下示例演示了封装。
public class Student
{
private string _firstName;
public string FirstName
{
get { return _firstName; }
set { _firstName = value; }
}
private string _middleName;
public string MiddleName
{
get { return _middleName; }
set { _middleName = value; }
}
private string _lastName;
public string LastName
{
get { return _lastName; }
set { _lastName = value; }
}
public string FullName
{
get { return _firstName + " " + _lastName; }
}
public void Save() {
//write code to save student
}
public void Subscribe(Course cs)
{
Verify();
//write code to subscribe to a course
}
private void Verify()
{
//write code to verify student before subscribing
}
public void GetSubscribedCourses()
{
//write code to return all subscribed courses
}
}
上面,私有字段(如 _firstName
、_middleName
和 _lastName
)私密地存储数据,以将其隐藏在外部代码之外,从而使它们无法用无效值修改数据。FirstName
、MiddleName
和 LastName
属性在 getter 和 setter 中使用这些字段来返回和设置这些字段的值。这些是公共属性,因此它们通过 getter 和 setter 对外部代码可见和可访问。FullName
属性在内部使用私有变量来返回学生的完整姓名。
同样,公共 Enroll()
方法是可见的,但它通过内部调用私有 Subscribe()
方法来隐藏实现细节。外部代码无法知道和访问 Subscribe()
方法,因为它是私有方法。
封装的优点
- 隐藏数据和复杂性。
- 通过在数据访问之前进行授权来限制对数据的未经授权访问。
- 允许在设置数据之前进行验证。
- 只有类的作者需要理解实现,而不是其他人。
- 使应用程序易于维护。