C# 中的封装与访问修饰符

封装是面向对象编程(OOP)中的核心概念之一,它的作用是隐藏对象的内部实现细节,只暴露必要的接口,以便外部代码能够与之交互。在 C# 中,封装通过访问修饰符来实现。访问修饰符决定了类成员(如字段、属性和方法)能被哪些代码访问。这篇文章将深入探讨 C# 中的封装,解释不同的访问修饰符,并通过示例帮助理解。

一、封装的定义

封装可以被定义为"将一个或多个项目封闭在一个物理或逻辑的包中"。在面向对象编程中,封装的主要目的是隐藏实现细节,暴露接口。通过封装,程序员可以控制类内部数据的访问权限,并根据需要决定哪些信息可以被外部代码访问。

封装与抽象密切相关,抽象允许开发者设计类的高层次接口,封装则实现了对类的具体实现细节的控制。简而言之,封装是实现抽象的一种手段。

二、访问修饰符

C# 提供了多种访问修饰符来控制类成员的可见性和访问范围。下面列出的是 C# 中常用的访问修饰符:

  • public:该成员对所有代码都可见,其他类和程序集可以访问。
  • private:该成员只能在本类中访问,外部类无法访问。
  • protected:该成员只能在本类及其派生类中访问。
  • internal:该成员只能在当前程序集中访问,其他程序集无法访问。
  • protected internal:该成员可以在当前程序集内访问,也可以在派生类中访问。

接下来,我们将通过一些代码示例来深入理解这些访问修饰符。

1. Public 访问修饰符

public 访问修饰符意味着类的成员对所有外部代码都是可见的。在使用 public 修饰符时,可以直接访问类的字段或方法。

示例:
csharp 复制代码
using System;

namespace RectangleApplication
{
    class Rectangle
    {
        // 公共成员变量
        public double length;
        public double width;

        public double GetArea()
        {
            return length * width;
        }

        public void Display()
        {
            Console.WriteLine("长度: {0}", length);
            Console.WriteLine("宽度: {0}", width);
            Console.WriteLine("面积: {0}", GetArea());
        }
    }

    class ExecuteRectangle
    {
        static void Main(string[] args)
        {
            Rectangle r = new Rectangle();
            r.length = 4.5;
            r.width = 3.5;
            r.Display();
            Console.ReadLine();
        }
    }
}

输出:

复制代码
长度: 4.5
宽度: 3.5
面积: 15.75

在上面的代码中,length 和 width 都被声明为 public,因此它们可以被外部类 ExecuteRectangle 直接访问。这就是封装的一个简单例子,使用 public 访问修饰符暴露了类的部分成员。

2. Private 访问修饰符

private 访问修饰符意味着类的成员只能在本类内部访问,外部无法直接访问。这有助于保护对象的状态,只允许通过类提供的公共方法来修改或获取数据。

示例:
csharp 复制代码
using System;

namespace RectangleApplication
{
    class Rectangle
    {
        // 私有成员变量
        private double length;
        private double width;

        // 公共方法,用于设置矩形的长度和宽度
        public void AcceptDetails()
        {
            Console.WriteLine("请输入长度:");
            length = Convert.ToDouble(Console.ReadLine());
            Console.WriteLine("请输入宽度:");
            width = Convert.ToDouble(Console.ReadLine());
        }

        // 公共方法,用于计算矩形的面积
        public double GetArea()
        {
            return length * width;
        }

        // 公共方法,用于显示矩形的属性和面积
        public void Display()
        {
            Console.WriteLine("长度: {0}", length);
            Console.WriteLine("宽度: {0}", width);
            Console.WriteLine("面积: {0}", GetArea());
        }
    }

    class ExecuteRectangle
    {
        static void Main(string[] args)
        {
            // 创建 Rectangle 类的实例
            Rectangle r = new Rectangle();

            // 通过公有方法 AcceptDetails() 获取矩形的长度和宽度
            r.AcceptDetails();

            // 通过公有方法 Display() 显示矩形的属性和面积
            r.Display();

            Console.ReadLine();
        }
    }
}

输出:

复制代码
请输入长度:
5
请输入宽度:
3
长度: 5
宽度: 3
面积: 15

在这个示例中,length 和 width 被声明为 private,因此它们无法直接在外部访问。我们通过公共方法 AcceptDetails() 来获取用户输入,并通过 Display() 方法来显示矩形的属性。这样就实现了对类内部数据的保护。

3. Protected 访问修饰符

protected 访问修饰符意味着成员只能在当前类及其派生类中访问。它通常用于继承中,让子类可以访问基类的成员。

示例:
csharp 复制代码
using System;

namespace RectangleApplication
{
    class Rectangle
    {
        // 保护成员变量
        protected double length;
        protected double width;

        public void SetDimensions(double l, double w)
        {
            length = l;
            width = w;
        }
    }

    class Square : Rectangle
    {
        public void Display()
        {
            Console.WriteLine("边长: {0}", length); // 继承自 Rectangle 类
        }
    }

    class ExecuteRectangle
    {
        static void Main(string[] args)
        {
            Square s = new Square();
            s.SetDimensions(5.0, 5.0);
            s.Display();

            Console.ReadLine();
        }
    }
}

输出:

复制代码
边长: 5

在上面的代码中,length 和 width 使用 protected 访问修饰符,因此可以在 Square 类中访问。这是通过继承实现的,Square 作为 Rectangle 的派生类,可以访问基类的受保护成员。

4. Internal 访问修饰符

internal 访问修饰符允许在同一程序集中的其他类访问该成员,但不允许外部程序集访问。它是限制访问范围的一种方式。

示例:
csharp 复制代码
using System;

namespace RectangleApplication
{
    class Rectangle
    {
        // 内部成员变量
        internal double length;
        internal double width;

        public double GetArea()
        {
            return length * width;
        }

        public void Display()
        {
            Console.WriteLine("长度: {0}", length);
            Console.WriteLine("宽度: {0}", width);
            Console.WriteLine("面积: {0}", GetArea());
        }
    }

    class ExecuteRectangle
    {
        static void Main(string[] args)
        {
            Rectangle r = new Rectangle();
            r.length = 4.5;
            r.width = 3.5;
            r.Display();
            Console.ReadLine();
        }
    }
}

输出:

复制代码
长度: 4.5
宽度: 3.5
面积: 15.75

在这个示例中,length 和 width 使用 internal 修饰符,因此它们可以在同一程序集内的任何类中访问。

5. Protected Internal 访问修饰符

protected internal 访问修饰符意味着成员可以在当前程序集中访问,也可以在派生类中访问。

示例:
csharp 复制代码
using System;

namespace RectangleApplication
{
    class Rectangle
    {
        // 保护内部成员变量
        protected internal double length;
        protected internal double width;

        public double GetArea()
        {
            return length * width;
        }

        public void Display()
        {
            Console.WriteLine("长度: {0}", length);
            Console.WriteLine("宽度: {0}", width);
            Console.WriteLine("面积: {0}", GetArea());
        }
    }

    class ExecuteRectangle
    {
        static void Main(string[] args)
        {
            Rectangle r = new Rectangle();
            r.length = 4.5;
            r.width = 3.5;
            r.Display();
            Console.ReadLine();
        }
    }
}

输出:

复制代码
长度: 4.5
宽度: 3.5
面积: 15.75

在这里,length 和 width 被声明为 protected internal,因此可以在当前程序集内的任何类中访问,也可以在派生类中访问。

三、总结

通过合理使用访问修饰符,C# 提供了一种强大的方式来实现封装,保护对象的内部状态,并提供清晰的接口与外部交互。封装

相关推荐
周杰伦fans12 小时前
8GB显存下模型量化实战指南
人工智能·后端·c#
samble14 小时前
从零搭建灌装监控系统(十二):配置系统,原子写入与容错
c#·wpf·mvvm·modbus·工业控制
流形填表18 小时前
题库去重实战:基于题干指纹的重复题清理
开发语言·c#
开开心心就好1 天前
以图搜图找重复图片,本地工具离线就能用
javascript·智能手机·ffmpeg·c#·ocr·word·音视频
QQ_21696290961 天前
基于C#(Asp.net)电竞陪玩信息管理系统的设计与实现
java·大数据·spring boot·微信小程序·c#·云计算·asp.net
未来之窗软件服务1 天前
C# 截图源码支持自动保存-东方仙盟
c#·仙盟创梦ide·东方仙盟·电脑工具
UIU1142 天前
-7 / 2 在 C 里是 -3,在 Python 里是 -4,谁算错了?
c++·学习·c#
wflynn2 天前
GitHub 今日推荐|REDox:64 位 token 表示结构化数据,内存占用降 70% 支持多格式互转
开源·c#·github
驰骋工作流2 天前
C#/.NET 开源BPM工作流引擎6大常用对比选型分析驰骋BPM驰骋低代码低代码工作流引擎
开源·c#·.net
en.en..2 天前
C语言 fp与fd 区别详解
c#