文章大纲
加载中...

C#教程5:访问修饰符

3/30/2025 61 阅读
C#教程5:访问修饰符

一、访问修饰符概述

访问修饰符是C#中用于控制类型及其成员的可访问性和可见性的关键字。它们决定了代码的哪些部分可以访问特定的类型或成员,是实现封装原则的重要工具。

二、C#中的访问修饰符

C#提供了以下几种访问修饰符:

1. public

  • 可见范围:无限制,任何代码都可以访问
  • 适用对象:类、接口、结构、枚举、委托、方法、属性、字段等
  • 使用场景:需要被外部程序集访问的成员

2. private

  • 可见范围:仅在声明它的类或结构内部可见
  • 适用对象:类成员、结构成员
  • 使用场景:实现类的内部细节,不希望外部访问的成员

3. protected

  • 可见范围:在声明它的类内部以及派生类中可见
  • 适用对象:类成员
  • 使用场景:需要在继承层次结构中共享,但不希望外部访问的成员

4. internal

  • 可见范围:仅在当前程序集内可见
  • 适用对象:类、接口、结构、枚举、委托、方法、属性、字段等
  • 使用场景:需要在同一程序集内共享,但不希望被外部程序集访问的成员

5. protected internal

  • 可见范围:在当前程序集内或派生类中可见
  • 适用对象:类成员
  • 使用场景:需要在同一程序集内共享,并且允许其他程序集中的派生类访问的成员

6. private protected (C# 7.2及以上)

  • 可见范围:仅在当前程序集内的派生类中可见
  • 适用对象:类成员
  • 使用场景:需要限制成员只能被同一程序集中的派生类访问的情况

三、访问修饰符的可见性范围

访问修饰符 当前类 派生类(同程序集) 派生类(不同程序集) 非派生类(同程序集) 非派生类(不同程序集)
public
private
protected
internal
protected internal
private protected

四、代码示例

using System;

// 公共类,可以被任何代码访问
public class Person
{
    // 公共字段,可以被任何代码访问
    public string Name;
    
    // 私有字段,只能在Person类内部访问
    private int age;
    
    // 受保护字段,只能在Person类及其派生类中访问
    protected string idNumber;
    
    // 内部字段,只能在当前程序集内访问
    internal string address;
    
    // 受保护内部字段,可以在当前程序集内或派生类中访问
    protected internal string phoneNumber;
    
    // 私有受保护字段,只能在当前程序集内的派生类中访问
    private protected string medicalRecord;
    
    // 公共构造函数
    public Person(string name, int age)
    {
        Name = name;
        this.age = age;
    }
    
    // 公共方法
    public void Introduce()
    {
        Console.WriteLine($"你好,我是{Name},今年{age}岁。");
    }
    
    // 私有方法
    private void UpdateMedicalRecord(string record)
    {
        medicalRecord = record;
        Console.WriteLine("医疗记录已更新。");
    }
    
    // 受保护方法
    protected void ShowIdNumber()
    {
        Console.WriteLine($"身份证号:{idNumber}");
    }
    
    // 内部方法
    internal void ChangeAddress(string newAddress)
    {
        address = newAddress;
        Console.WriteLine($"地址已更改为:{address}");
    }
    
    // 公共属性,带有私有设置器
    public int Age
    {
        get { return age; }
        private set { age = value; }
    }
}

// 派生类
public class Employee : Person
{
    // 私有字段
    private string employeeId;
    
    // 公共构造函数
    public Employee(string name, int age, string employeeId) : base(name, age)
    {
        this.employeeId = employeeId;
        
        // 可以访问基类的受保护成员
        this.idNumber = "123456789";
        
        // 可以访问基类的受保护内部成员
        this.phoneNumber = "13800138000";
        
        // 可以访问基类的私有受保护成员(如果在同一程序集内)
        this.medicalRecord = "健康状况良好";
        
        // 不能访问基类的私有成员
        // this.age = 30; // 编译错误
    }
    
    // 公共方法
    public void DisplayEmployeeInfo()
    {
        Console.WriteLine($"员工ID:{employeeId}");
        
        // 可以调用基类的受保护方法
        ShowIdNumber();
        
        // 不能调用基类的私有方法
        // UpdateMedicalRecord("新记录"); // 编译错误
    }
}

// 内部类,只能在当前程序集内访问
internal class Department
{
    public string Name { get; set; }
    
    public Department(string name)
    {
        Name = name;
    }
}

class Program
{
    static void Main(string[] args)
    {
        // 创建Person对象
        Person person = new Person("张三", 30);
        
        // 访问公共成员
        Console.WriteLine(person.Name);
        person.Introduce();
        
        // 不能访问私有成员
        // Console.WriteLine(person.age); // 编译错误
        // person.UpdateMedicalRecord("新记录"); // 编译错误
        
        // 不能访问受保护成员
        // person.ShowIdNumber(); // 编译错误
        
        // 可以访问内部成员(因为在同一程序集内)
        person.ChangeAddress("北京市海淀区");
        
        // 创建Employee对象
        Employee employee = new Employee("李四", 25, "EMP001");
        employee.DisplayEmployeeInfo();
        
        // 创建内部类对象(因为在同一程序集内)
        Department department = new Department("研发部");
        Console.WriteLine($"部门名称:{department.Name}");
        
        Console.ReadKey();
    }
}

五、访问修饰符的最佳实践

  1. 封装原则:尽可能使用最严格的访问级别,只公开必要的成员

  2. 公共API设计

    • 公共API应该使用public修饰符
    • 实现细节应该使用privateprotected隐藏
  3. 程序集设计

    • 程序集内部共享的类型使用internal
    • 跨程序集共享的类型使用public
  4. 继承设计

    • 基类中需要被派生类重写或访问的成员使用protected
    • 基类中只在内部使用的成员使用private
  5. 安全性考虑

    • 敏感数据和操作应该使用private保护
    • 避免过度暴露内部实现细节

六、课后作业

作业:银行账户系统

设计一个简单的银行账户系统,使用不同的访问修饰符来保护数据和操作的安全性:

  1. 创建一个BankAccount类,包含以下成员:

    • 私有字段:accountNumberbalancepin(密码)
    • 受保护字段:accountType
    • 公共属性:AccountHolder(账户持有人)
    • 内部属性:LastActivityDate(最后活动日期)
    • 公共方法:Deposit()Withdraw()GetBalance()
    • 私有方法:ValidatePin()
    • 受保护方法:CalculateInterest()
  2. 创建一个派生类SavingsAccount,继承自BankAccount,添加特定于储蓄账户的功能。

  3. 创建一个派生类CheckingAccount,继承自BankAccount,添加特定于支票账户的功能。

  4. 在主程序中演示如何使用这些类,并说明各种访问修饰符如何保护数据安全。

完成此作业将帮助你理解如何在实际应用中正确使用访问修饰符来实现封装和保护数据安全。


评论 (0)

暂无评论,来发表第一条评论吧!