欢迎光临
我们一直在努力

C# 封装(Encapsulation)详解

封装(Encapsulation)是面向对象编程(OOP)的四大特性之一,另外三个是:

  • 继承(Inheritance)
  • 多态(Polymorphism)
  • 抽象(Abstraction)

封装的核心思想:

隐藏对象内部实现细节,只向外暴露必要的功能接口。

简单理解:

  • 数据(字段)放在类内部
  • 外部不能随意修改
  • 通过属性、方法控制访问

一、为什么需要封装

假设有一个学生类:

class Student
{
public int Age;
}

使用:

Student stu = new Student();

stu.Age = -100;

虽然语法正确,但年龄不可能是负数。

为了防止非法数据,需要封装。


二、使用 private 封装字段

class Student
{
private int age;

public void SetAge(int value)
{
if (value > 0)
{
age = value;
}
}

public int GetAge()
{
return age;
}
}

调用:

Student stu = new Student();

stu.SetAge(18);

Console.WriteLine(stu.GetAge());

结果:

18


三、访问修饰符

C# 使用访问修饰符实现封装。

修饰符访问范围
public 任何地方
private 当前类内部
protected 当前类和子类
internal 当前程序集
protected internal 当前程序集或子类

示例:

class Person
{
public string Name;

private int age;
}

外部:

Person p = new Person();

p.Name = "Tom"; //可以

p.age = 18; //错误


四、属性(Property)封装

实际开发最常用。

传统写法

class Student
{
private int age;

public int Age
{
get
{
return age;
}

set
{
if (value > 0)
{
age = value;
}
}
}
}

使用:

Student stu = new Student();

stu.Age = 20;

Console.WriteLine(stu.Age);

输出:

20


五、get 和 set

get

读取属性值

Console.WriteLine(stu.Age);

执行:

get
{
return age;
}


set

赋值属性值

stu.Age = 18;

执行:

set
{
age = value;
}

其中:

value

表示赋给属性的值。

例如:

stu.Age = 18;

那么:

value == 18


六、自动属性

如果不需要验证逻辑:

class Student
{
public int Age { get; set; }
}

编译器自动生成私有字段。

使用:

Student stu = new Student();

stu.Age = 18;


七、只读属性

方式1

public string Name { get; }

只能读取:

public class Student
{
public string Name { get; }

public Student(string name)
{
Name = name;
}
}


方式2

public string Name { get; private set; }

外部只能读:

Student stu = new Student();

Console.WriteLine(stu.Name);

// stu.Name = "Tom"; 错误

类内部可修改:

Name = "Jerry";


八、封装业务逻辑

例如银行卡余额:

class BankAccount
{
private decimal balance;

public decimal Balance
{
get { return balance; }
}

public void Deposit(decimal money)
{
if (money > 0)
{
balance += money;
}
}

public bool Withdraw(decimal money)
{
if (money <= balance)
{
balance -= money;
return true;
}

return false;
}
}

使用:

BankAccount account = new BankAccount();

account.Deposit(1000);

account.Withdraw(300);

Console.WriteLine(account.Balance);

结果:

700

优点:

  • 防止余额被随意修改
  • 保证业务规则正确
  • 数据更安全

九、封装与字段的区别

❌ 不推荐:

public string Name;

任何人都能直接修改:

obj.Name = "";
obj.Name = null;


✅ 推荐:

private string name;

public string Name
{
get { return name; }

set
{
if (!string.IsNullOrEmpty(value))
{
name = value;
}
}
}


十、完整案例

using System;

class Employee
{
private string name;
private decimal salary;

public string Name
{
get { return name; }

set
{
if (!string.IsNullOrWhiteSpace(value))
{
name = value;
}
}
}

public decimal Salary
{
get { return salary; }

set
{
if (value >= 0)
{
salary = value;
}
}
}

public void ShowInfo()
{
Console.WriteLine($"姓名:{Name}");
Console.WriteLine($"工资:{Salary}");
}
}

class Program
{
static void Main()
{
Employee emp = new Employee();

emp.Name = "张三";
emp.Salary = 8000;

emp.ShowInfo();
}
}

输出:

姓名:张三
工资:8000


实际开发最佳实践

现代 C#(C# 8+)中推荐:

public class User
{
public string UserName { get; set; }

public int Age { get; private set; }

public User(string userName, int age)
{
UserName = userName;

if (age < 0)
throw new ArgumentException("年龄不能小于0");

Age = age;
}
}

原则:

  • 字段尽量使用 private
  • 对外优先暴露属性(Property)
  • 在 set 中做数据验证
  • 重要业务数据通过方法操作,不直接开放 set
  • 保持“高内聚、低耦合”,隐藏实现细节
  • 一句话总结:

    C# 封装 = private 字段 + Property 属性 + 方法控制访问,目的是保护数据安全、隐藏实现细节、保证对象状态合法。

    赞(0)
    未经允许不得转载:171主机测评 » C# 封装(Encapsulation)详解
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址