006集—— 修饰符(public、private 、internal等)——C#学习笔记

发布于:2024-08-10 ⋅ 阅读:(143) ⋅ 点赞:(0)

封装 被定义为"把一个或多个项目封闭在一个物理的或者逻辑的包中"。在面向对象程序设计方法论中,封装是为了防止对实现细节的访问。

抽象和封装是面向对象程序设计的相关特性。抽象允许相关信息可视化,封装则使开发者实现所需级别的抽象。

C# 封装根据具体的需要,设置使用者的访问权限,并通过 访问修饰符 来实现。

一个 访问修饰符 定义了一个类成员的范围和可见性。C# 支持的访问修饰符如下所示:

声明的可访问性 含义
public 访问不受限制。
protected 访问限于包含类或派生自包含类的类型。
internal 访问限于当前程序集。
protected internal 访问限于当前程序集或派生自包含类的类型。
private 访问限于包含类。
private protected 访问限于包含类或当前程序集中派生自包含类的类型。
成员 默认成员可访问性 允许的成员的声明的可访问性
enum public
class private public

protected

internal

private

protected internal

private protected
interface public public

protected

internal

private*

protected internal

private protected
struct private public

internal

private

 * 具有 private 可访问性的 interface 成员必须具有默认的实现。

 备注

如果使用 record 关键字修饰符修改类或结构,则允许相同的访问修饰符。
此外,使用 record 修饰符,类和结构的默认成员可访问性仍然为 private

Public 访问修饰符

Public 访问修饰符允许一个类将其成员变量和成员函数暴露给其他的函数和对象。任何公有成员可以被外部的类访问。

以下代码展示不同访问修饰符的区别和应用:

代码如下:

using System;

// 定义一个命名空间  
namespace 空间1
{
    // 外部类,用于展示不同访问级别的成员  
    public class 外部类1
    {
        // Public 成员,任何地方都可以访问  
        public int PublicField = 1;

        // Private 成员,只能在定义它的类内部访问  
        private int PrivateField = 2;

        // Internal 成员,只能在同一个程序集(Assembly)内访问  
        internal int InternalField = 3;

        // Protected 成员,只能在定义它的类及其子类中访问  
        // 这里不直接展示,因为需要子类来演示  

        // Protected Internal 成员,在同一个程序集内的任何类或子类中都可以访问  
        protected internal int ProtectedInternalField = 4;

        // 构造函数  
        public 外部类1()
        {
            Console.WriteLine($"PublicField: {PublicField}");
            Console.WriteLine($"PrivateField: {PrivateField}"); // 内部访问,有效  
            Console.WriteLine($"InternalField: {InternalField}"); // 内部访问,有效  
            Console.WriteLine($"ProtectedInternalField: {ProtectedInternalField}"); // 内部访问,有效  
        }

        // Public 方法,用于展示如何访问不同访问级别的成员  
        public void ShowFields()
        {
            Console.WriteLine($"PublicField: {PublicField}");
            Console.WriteLine($"PrivateField: {PrivateField}"); // 内部访问,有效  
            Console.WriteLine($"InternalField: {InternalField}"); // 内部访问,有效  
            Console.WriteLine($"ProtectedInternalField: {ProtectedInternalField}"); // 内部访问,有效  
        }
    }

    // 子类,用于展示protected和protected internal的访问  
    public class 子类1 : 外部类1
    {
        public 子类1()
        {
            // 可以访问protected和protected internal成员,因为我们在同一个程序集内且是子类  
            Console.WriteLine($"Inherited ProtectedInternalField: {ProtectedInternalField}");
            // 注意:这里不能直接访问PrivateField,因为它是私有的  
            // 如果尝试访问PrivateField,则会编译错误  
        }

        // 演示访问protected和protected internal的方法  
        public void ShowInheritedFields()
        {
            // 可以访问从外部类1继承的protected和protected internal成员  
            Console.WriteLine($"Inherited ProtectedInternalField: {ProtectedInternalField}");
            // 注意:这里不能直接访问PrivateField,因为它是私有的  
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            外部类1 outer = new 外部类1();
            outer.ShowFields(); // 可以访问外部类1的public和internal成员  

            // 尝试访问private成员会导致编译错误  
            // Console.WriteLine($"PrivateField from Main: {outer.PrivateField}"); // 编译错误  

            // 演示子类  
            子类1 子类1 = new 子类1();
            子类1.ShowInheritedFields(); // 演示从外部类1继承的protected和protected internal成员的访问  

            // 注意:由于Main在空间1命名空间中,所以它可以访问internal成员  
            // 但如果Main在另一个命名空间中且不属于同一个程序集,则不能访问InternalField  

            // 保持控制台开启  
            Console.WriteLine("Press any key to exit...");
            Console.ReadKey();
        }
    }
}

 

以下为官方代码:


public class 函数
{
    public static int publicInt;
    internal static int internalInt;
    private static int privateInt = 0;

    static  函数()
    {
        // T1 can access public or internal members
        // in a public or private (or internal) nested class.
        M1.publicInt = 1;
        M1.internalInt = 2;
        M2.publicInt = 3;
        M2.internalInt = 4;

        // Cannot access the private member privateInt
        // in either class:
        // M1.privateInt = 2; //CS0122
    }

    public class M1
    {
        public static int publicInt;
        internal static int internalInt;
        private static int privateInt = 0;
    }

    private class M2
    {
        public static int publicInt = 0;
        internal static int internalInt = 0;
        private static int privateInt = 0;
    }
}

class MainClass
{
    static void Main()
    {
        // Access is unlimited.
        函数.publicInt = 1;

        // Accessible only in current assembly.
        函数.internalInt = 2;

        // Error CS0122: inaccessible outside T1.
        // T1.privateInt = 3;

        // Access is unlimited.
        函数.M1.publicInt = 1;

        // Accessible only in current assembly.
        函数.M1.internalInt = 2;

        // Error CS0122: inaccessible outside M1.
        //    函数.M1.privateInt = 3;

        // Error CS0122: inaccessible outside T1.
        //    函数.M2.publicInt = 1;

        // Error CS0122: inaccessible outside T1.
        //    函数.M2.internalInt = 2;

        // Error CS0122: inaccessible outside M2.
        //   函数.M2.privateInt = 3;

        // Keep the console open in debug mode.
        System.Console.WriteLine("Press any key to exit.");
        System.Console.ReadKey();
    }
}

 


网站公告

今日签到

点亮在社区的每一天
去签到