访问修饰符
本课属于 Coddy C# 学习旅程的“面向对象编程”单元。第 31 课,共 70 课。
访问修饰符用于控制谁可以查看和使用类成员。它们是封装的基础,而封装是 OOP 的核心原则之一。通过限制访问,你可以保护数据,并在代码中划分清晰的边界。
C# 提供了 4 种主要的访问修饰符:
public class BankAccount
{
public string AccountHolder; // 可以从任何地方访问
private decimal balance; // 只能在此类内部访问
protected string accountType; // 可以在此类及其派生类中访问
internal int branchCode; // 可以在同一程序集中访问
}public 成员可以被任何代码访问。
private 成员只能在同一个类中访问,这是限制最严格的访问级别,也是类成员的默认访问级别。
protected 允许类本身及任何继承它的类访问。
internal 将代码的访问范围限制在同一程序集(项目)内。
未指定修饰符时,类成员默认是 private:
class Example
{
int secret; // 默认是私有的
}选择合适的访问级别,就是只公开必要的内容。从 private 开始,只有在有明确理由时才提高可见性。这样可以避免其他代码依赖你之后可能想要更改的实现细节。
挑战
简单让我们构建一个安全的用户资料系统,展示访问修饰符如何保护敏感数据,同时只公开必要的信息。你将创建一个类,根据访问者的身份,为不同的信息设置不同的可见级别。
你需要将代码分成三个文件:
UserProfile.cs:在Security命名空间中创建一个UserProfile类,用合适的访问级别管理用户信息。用户资料应包含:- 一个
public属性Username(字符串),任何人都可以查看用户名 - 一个
private字段password(字符串),只有类本身可以访问 - 一个
protected字段email(字符串),该类及其子类可以访问 - 一个
internal字段userId(整数),可在同一程序集内访问
GetPublicInfo()的public方法,返回"User: {Username}"。再添加一个名为ValidatePassword(string input)的public方法:如果输入与私有密码匹配,则返回true,否则返回false。- 一个
AdminProfile.cs:在Security命名空间中创建一个继承自UserProfile的AdminProfile类。这个类展示了protected成员如何在派生类中变得可访问。构造函数应接受相同的四个参数,并将它们传递给基类构造函数。添加一个名为GetAdminInfo()的public方法,返回"Admin: {Username}, Email: {email}",注意,你可以在这里访问受保护的email字段!Program.cs:在主文件中,使用输入值创建一个UserProfile和一个AdminProfile。通过调用可用的公共方法并直接访问内部字段(因为你位于同一程序集内)来展示不同的访问级别。显示每种用户类型可以公开哪些信息。
你将收到五个输入值:
- 用户名
- 密码
- 电子邮件
- 用户 ID(整数)
- 要验证的密码尝试
按以下格式输出:
Regular User:
{GetPublicInfo() result}
Internal ID: {userId}
Password valid: {ValidatePassword result}
Admin User:
{GetAdminInfo() result}例如,如果输入是 alice、secret123、alice@email.com、1001 和 secret123,输出应为:
Regular User:
User: alice
Internal ID: 1001
Password valid: True
Admin User:
Admin: alice, Email: alice@email.com请注意,密码始终完全隐藏,你只能验证密码,不能读取它。电子邮件受到保护,因此只有 AdminProfile(派生类)可以公开它。由于主文件位于同一程序集内,因此可以访问内部字段 userId。这就是封装的实际应用!
亲手试试
using System;
using Security;
class Program
{
public static void Main(string[] args)
{
// 读取输入
string username = Console.ReadLine();
string password = Console.ReadLine();
string email = Console.ReadLine();
int userId = Convert.ToInt32(Console.ReadLine());
string passwordAttempt = Console.ReadLine();
// TODO:用输入值创建一个 UserProfile 对象
// TODO:用相同的输入值创建一个 AdminProfile 对象
// TODO:打印 "Regular User:"
// TODO:打印 GetPublicInfo() 的结果
// TODO:先打印 "Internal ID: ",再打印 userId 字段(因为在同一程序集内,所以可以访问)
// TODO:先打印 "Password valid: ",再打印 ValidatePassword() 的结果
// TODO:打印 "Admin User:"
// TODO:打印 GetAdminInfo() 的结果
}
}
这节课包含一个小测验。开始学习即可作答,并记录你的进度。
面向对象编程中的所有课
自己练习: C# 在线编译器