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

在上面的代码中,lengthwidth 都被声明为 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

在这个示例中,lengthwidth 被声明为 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

在上面的代码中,lengthwidth 使用 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

在这个示例中,lengthwidth 使用 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

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

三、总结

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

相关推荐
游乐码3 小时前
c#成员属性
开发语言·c#
Never_Satisfied4 小时前
在c#中,如何删除字符串中的第x个字符
开发语言·c#
Never_Satisfied4 小时前
在c#中,缩放jpg文件的尺寸
算法·c#
Never_Satisfied5 小时前
在c#中,控件的事件执行耗时操作导致窗体无法及时处理绘制、鼠标点击
开发语言·c#
zls3653655 小时前
C# WPF canvas中绘制缺陷分布map并实现缩放
开发语言·c#·wpf
Never_Satisfied6 小时前
在c#中,如何在字符串的第x个字符位置插入字符
java·开发语言·c#
bugcome_com20 小时前
C# 常量详解:从基础语法到实际应用
c#
qq_1508419921 小时前
3天基于VS2026的C#编程入门及动态调用CH341DLLA64读写I2C从机
开发语言·c#
溪水西流1 天前
NodifyEditor Zoom 机制分析
开发语言·c#·avalonia