C#封装用法详解(附带实例)
在 C# 程序中,我们可以从顶级语句直接引用所设计的类内的成员变量(属性)和方法,像这种类内的成员变量可以让外部引用的称为公有属性,而可以让外部引用的方法称为公有方法。
所有类的属性与方法可供外部随意存取,这个设计概念最大的风险就是会有信息安全的疑虑。
【实例 1】下面是一个简单的 Bank 类,这个类创建对象完成后,会将存款金额(balance)设为 0,但是我们可以在顶级语句中随意设定 balance,即可以获得目前的存款余额。
为了确保类内成员变量(属性值)的安全,有必要限制外部使其无法直接存取类内的成员变量(属性值)。这其实就是将类的成员变量隐藏起来,未来如果想要存取被隐藏的成员变量,就需使用此类的方法,外部无法得知类内是如何运作的,这个概念就是所谓的封装(encapsulation),有时候又称信息隐藏(information hiding)。此时程序设计的概念应如下所示:
上述列表指出了类成员有关存取修饰符的权限,下列将分别说明:
为了可以存取这些 private 的成员变量,我们必须在 Bank 类内设计可以供顶级语句设定并取得存款金额的程序。
【实例 2】将 Bank 类数据 balance 设为 private,然后顶级语句无法存取,需使用 public 类的 void SetBalance()方法和int GetBalance() 方法,来设定并取得存款余额。
【实例 3】使用下面线定义成员变量。
所有类的属性与方法可供外部随意存取,这个设计概念最大的风险就是会有信息安全的疑虑。
【实例 1】下面是一个简单的 Bank 类,这个类创建对象完成后,会将存款金额(balance)设为 0,但是我们可以在顶级语句中随意设定 balance,即可以获得目前的存款余额。
Bank A = new Bank("Hung"); A.GetBalance(); A.balance = 1000; A.GetBalance(); public class Bank { public int balance; public string name; public Bank(string name) { this.name = name; this.balance = 0; } public void GetBalance() { Console.WriteLine($"{name} 目前存款余额 {this.balance}"); } }执行结果为:
Hung 目前存款余额 0
Hung 目前存款余额 1000

为了确保类内成员变量(属性值)的安全,有必要限制外部使其无法直接存取类内的成员变量(属性值)。这其实就是将类的成员变量隐藏起来,未来如果想要存取被隐藏的成员变量,就需使用此类的方法,外部无法得知类内是如何运作的,这个概念就是所谓的封装(encapsulation),有时候又称信息隐藏(information hiding)。此时程序设计的概念应如下所示:

C#类成员的访问控制
到目前为止,笔者所设计的类内的方法大都没有加上 public 存取修饰符(access modifier),其实可以将访问控制分成 6 个等级。位置 | public | protected internal | protected | internal | private protected | private |
---|---|---|---|---|---|---|
类内 | Y | Y | Y | Y | Y | Y |
衍生类 (相同项目) |
Y | Y | Y | Y | Y | N |
非衍生类 (相同项目) |
Y | Y | N | Y | N | N |
衍生类 (不同项目) |
Y | Y | Y | N | N | N |
非衍生类 (不同项目) |
Y | N | N | N | N | N |
上述列表指出了类成员有关存取修饰符的权限,下列将分别说明:
- public:可解释为公开,如果我们将类的成员变量或方法设为 public,则本身类(class)、衍生类(derived class)或其他类(world)都可以存取;
- protected internal:可解释为保护,如果我们将类的成员变量或方法设为 protected internal,则本身类或衍生类可以存取,相同项目的非衍生类也可以存取;
- protected:可解释为保护,如果我们将类的成员变量或方法设为 protected,则本身类或衍生类可以存取,衍生类的不同项目也可以存取;
- private protected:本身类、相同项目的衍生类可以存取;
- private:可解释为私有,如果我们将类的成员变量或方法设为 private,则除了本身类可以存取外,衍生类(derived class)或其他类都不可以存取。
C#设计具有封装效果的程序
这里继续用 Bank 的实例说明,程序设计时若是想要类内的成员变量(属性)是安全的,无法由外部随意存取,则必须将成员变量设计为 private,其实成员变量默认就是 private。为了可以存取这些 private 的成员变量,我们必须在 Bank 类内设计可以供顶级语句设定并取得存款金额的程序。
【实例 2】将 Bank 类数据 balance 设为 private,然后顶级语句无法存取,需使用 public 类的 void SetBalance()方法和int GetBalance() 方法,来设定并取得存款余额。
Bank A = new Bank(); A.SetBalance(1000); Console.WriteLine(A.GetBalance()); public class Bank { private int balance; // 默认的也是 private,所以也可以省略 private public void SetBalance(int balance) { this.balance = balance; // 设定存款余额 } public int GetBalance() { return balance; // 回传存款金额 } }执行结果为:
1000
上述程序中,为了区分传递参数的 balance 与类定义的 balance,笔者使用了 this 关键词,读者可以参考第 11 行,C# 程序设计时喜欢使用“下画线+变量名称”来定义类内的成员字段变量,读者可以参考下列实例。【实例 3】使用下面线定义成员变量。
Bank A = new Bank(); A.SetBalance(1000); Console.WriteLine(A.GetBalance()); public class Bank { private int _balance; // 默认的也是 private,所以也可以省略 private public void SetBalance(int balance) { _balance = balance; // 设定存款余额 } public int GetBalance() { return _balance; // 回传存款金额 } }执行结果与实例 2 相同。