C# -封装:初学者指南

你好,未来的编程超级巨星!今天,我们将踏上一段激动人心的旅程,探索C#世界的其中一个基本概念:封装。如果你之前从未编写过一行代码,不用担心——我会一步一步地引导你。那么,让我们开始吧!

C# - Encapsulation

什么是封装?

在我们深入了解之前,先来理解一下封装是什么。想象你有一个能做神奇事情的魔法盒子,但你不需要知道它内部是如何工作的——你只需要知道如何使用它。这就是封装的精髓!

在C#中,封装是将数据(变量)和操作这些数据的方法捆绑在一个单一的单位或对象中的过程。就像在你的代码周围创建一个保护性的胶囊,因此得名“封装”。

现在,让我们探索C#如何通过访问修饰符来实现封装。

C#中的访问修饰符

访问修饰符是定义类、方法或属性在代码中可访问性的关键字。可以把它们想象成不同级别的安全许可。C#提供了五个主要的访问修饰符:

  1. 公共(Public)
  2. 私有(Private)
  3. 保护(Protected)
  4. 内部(Internal)
  5. 保护内部(Protected Internal)

让我们一个一个来分解它们。

公共访问修饰符

public关键字就像一个“通行证”。当你将一个成员声明为public时,它可以从程序的任何部分访问。

public class Person
{
public string Name { get; set; }

public void SayHello()
{
Console.WriteLine($"你好,我的名字是{Name}!");
}
}

class Program
{
static void Main(string[] args)
{
Person person = new Person();
person.Name = "Alice";  // 访问公共属性
person.SayHello();  // 调用公共方法
}
}

在这个例子中,NameSayHello()都是public,所以我们可以直接从Main方法访问它们。

私有访问修饰符

现在,private就像一个“员工专用”区域。私有成员只能在同一个类内访问。

public class BankAccount
{
private double balance;

public void Deposit(double amount)
{
if (amount > 0)
{
balance += amount;
}
}

public double GetBalance()
{
return balance;
}
}

class Program
{
static void Main(string[] args)
{
BankAccount account = new BankAccount();
account.Deposit(100);
// account.balance = 1000000;  // 这将导致错误!
Console.WriteLine($"余额: {account.GetBalance()}");
}
}

在这里,balance是私有的,所以我们不能从BankAccount类的外部直接访问它。我们需要使用像Deposit()GetBalance()这样的公共方法来与它交互。

保护访问修饰符

protected成员在同一个类和派生类中都是可访问的。就像一个“家庭专用”部分。

public class Animal
{
protected string name;

public Animal(string name)
{
this.name = name;
}

protected void Eat()
{
Console.WriteLine($"{name}正在吃东西。");
}
}

public class Dog : Animal
{
public Dog(string name) : base(name) { }

public void Bark()
{
Console.WriteLine($"{name}正在吠叫!");  // 可以访问protected成员
Eat();  // 可以调用protected方法
}
}

class Program
{
static void Main(string[] args)
{
Dog dog = new Dog("Buddy");
dog.Bark();
// dog.name = "Max";  // 这将导致错误!
// dog.Eat();  // 这也将导致错误!
}
}

在这个例子中,Dog可以访问它的父类Animal中的protected成员nameEat()方法,但我们不能直接从Main方法访问这些。

内部访问修饰符

internal成员在同一程序集内(可以想象为一个编译的.dll或.exe文件)是可访问的。就像一个“公司员工专用”区域。

// 在AssemblyOne.cs中
internal class InternalClass
{
internal void InternalMethod()
{
Console.WriteLine("这是一个内部方法。");
}
}

// 在Program.cs中(同一程序集)
class Program
{
static void Main(string[] args)
{
InternalClass obj = new InternalClass();
obj.InternalMethod();  // 这有效!
}
}

// 在不同的程序集中,这将不起作用:
// InternalClass obj = new InternalClass();  // 错误!

保护内部访问修饰符

最后,protected internalprotectedinternal的组合。它可以在同一程序集内或由其他程序集中的派生类访问。

// 在AssemblyOne.cs中
public class BaseClass
{
protected internal void ProtectedInternalMethod()
{
Console.WriteLine("这是一个protected internal方法。");
}
}

// 在AssemblyTwo.cs中
public class DerivedClass : BaseClass
{
public void CallProtectedInternalMethod()
{
ProtectedInternalMethod();  // 这有效!
}
}

// 在Program.cs中(AssemblyTwo)
class Program
{
static void Main(string[] args)
{
DerivedClass obj = new DerivedClass();
obj.CallProtectedInternalMethod();
// obj.ProtectedInternalMethod();  // 这将不起作用!
}
}

访问修饰符总结

这里有一个方便的表格来总结访问级别:

访问修饰符 同一类别 派生类(同一程序集) 非派生类(同一程序集) 派生类(不同程序集) 非派生类(不同程序集)
公共
私有
保护
内部
保护内部

就是这样!你已经迈出了进入C#封装世界的第一步。记住,封装是关于控制对你的代码和数据的访问。它帮助你编写更安全、可维护和灵活的程序。

在你继续编程之旅时,你会发现封装变得习以为常。这就像学习骑自行车——一开始可能会有些摇晃,但很快你就能自如地骑行,而不用多加思考!

继续练习,保持好奇心,快乐编程!

Credits: Image by storyset