C# 学习笔记 - 2.4 - 封装

发布时间 2023-08-21 20:31:17作者: Snoopy1866

封装

封装可以阻止用户以开发者不希望的方式操纵对象。

所有类和结构体的默认受保护级别为“private”,这意味着外部用户无法访问类和结构体的内部成员。

受保护级别(Protection Levels)

Private

private 级别的成员只能在类的内部被访问,其他类的方法,甚至 private 级别成员所在类的衍生类均无法访问 private 级别的成员。private 是默认的受保护级别。

namespace PrivateSample
{
    public class Person
    {
        private string _name;

        // Methods
        public Person(string name)
        {
            // Private members can only be modified by the internal methods or constructors of class
            this._name = name; 
        }
    }

    public class Entry
    {
        static void Main(string[] args)
        {
            Person OnePerson = new Person("Samanta");
            //OnePerson._name = "Sam"; // This causes a error of access level
        }
    }
}

Protected

protected 级别的成员可以被类自身或者类的衍生类访问,但不能被其他类访问。

namespace ProtectedSample
{
    public class Person
    {
        protected string _name;
    }
    /// <summary>
    /// When a class inherits from other class, it can access your protected and public members
    /// above your created members
    /// </summary>
    public class Warrior : Person
    {
        public void SetName(string name)
        {
            // Protected members can be accessed by internal methods or constructors of class
            // so, it can be accessed by inherit class too
            base._name = name;
        }
    }

    public class Entry
    {
        static void Main(string[] args)
        {
            Warrior OnePerson = new Warrior();
            OnePerson.SetName("Glades"); // OK
            // OnePerson._name = "Sam"; // This causes a error of access level too
            // protected members can not be accessed by external scopes
        }
    }
}

Public

public 级别的成员可以被任何类中的任何方法访问。

namespace PublicSample
{
    public class Person
    {
        public string Name;
    }

    public class Entry
    {
        static void Main(string[] args)
        {
            Person BeautifulPerson = new Person();
            BeautifulPerson.Name = "Debora"; // OK, public member can be accessed by other scopes
        }
    }
}

注:将成员变量暴露给外部不是一个好的编程习惯(除非必须这么做)。

It is good programming practice not to expose member variables to the outside, unless it is necessary. This is true especially for fields that should only be accessible over accessor and mutator methods (getters and setters). Exceptions are member variables that are constant.

Internal

internal 级别的成员只能在相同的程序集中被访问。

namespace InternalSample
{
    public class Person
    {
        internal string Name;
    }

    public class Entry
    {
        static void Main(string[] args)
        {
            Person BeautifulPerson = new Person();
            BeautifulPerson.Name = "Debora"; // OK, internal member can be accessed by other 
            // scopes in same assembly supposing that Person is in another assembly, by example a 
            // library, the name cannot be accessed. In another assembly source, this causes an error:
            // BeautifulPerson.Name = "Debora"; // Cannot access internal member
        }
    }
}

Protected Internal

protected internal 级别的成员可以被同一程序集下的类及其衍生类访问。

namespace InternalSample
{
    public class Person
    {
        protected internal string Name;
    }

    public class Entry
    {
        static void Main(string[] args)
        {
            Person BeautifulPerson = new Person();
            BeautifulPerson.Name = "Debora"; // As above...
        }
    }
}

public class Book : InternalSample.Person
{
    static void Main(string[] args)
    {
        InternalSample.Person BeautifulPerson = new InternalSample.Person();
        string aName = BeautifulPerson.Name; // Can be accessed, as Book is derived from Person
    }
}

范围比较:

  • private < internal < public

  • private < protected < public

proctected : 决定衍生类是否有访问权限

internal : 决定程序集是否有访问权限

img