大家好,欢迎来到IT知识分享网。
(1) Pubilc :任何公有成员可以被外部的类访问。
(2) Private :只有同一个类中的函数可以访问它的私有成员。
(3) Protected :该类内部和继承类中可以访问。
(4) internal : 同一个程序集的对象可以访问。
(5) Protected internal :3 和 4 的并集,符合任意一条都可以访问。
封装
被定义为”把一个或多个项目封闭在一个物理的或者逻辑的包中”。在面向对象程序设计方法论中,封装是为了防止对实现细节的访问。
抽象和封装是面向对象程序设计的相关特性。抽象允许相关信息可视化,封装则使开发者实现所需级别的抽象。
C# 封装根据具体的需要,设置使用者的访问权限,并通过 访问修饰符 来实现。
一个 访问修饰符 定义了一个类成员的范围和可见性。C# 支持的访问修饰符如下所示:
声明的可访问性 | 含义 |
---|---|
public | 访问不受限制。 |
protected | 访问限于包含类或派生自包含类的类型。 |
internal | 访问限于当前程序集。 |
protected internal | 访问限于当前程序集或派生自包含类的类型。 |
private | 访问限于包含类。 |
private protected | 访问限于包含类或当前程序集中派生自包含类的类型。 |
成员 | 默认成员可访问性 | 允许的成员的声明的可访问性 |
---|---|---|
enum |
public |
无 |
class |
private |
public
|
interface | public | public
|
struct | private | public
|
* 具有 private
可访问性的 interface
成员必须具有默认的实现。
备注
Public 访问修饰符
Public 访问修饰符允许一个类将其成员变量和成员函数暴露给其他的函数和对象。任何公有成员可以被外部的类访问。
public
可见性:public 修饰的类、接口、方法、属性、字段等可以在任何其他地方被访问,无论这些成员位于哪个程序集(Assembly)中。public 成员是最开放的访问级别。
用途:当你希望一个类或成员被任何其他类访问时(无论是在同一个程序集中还是在不同的程序集中),应该使用 public 修饰符。例如,公共接口或API通常使用 public 修饰符。
private
访问范围:private修饰的类成员(如字段、方法、属性等)只能在定义它们的类内部被访问。这意味着,这些成员对于类的外部是不可见的,也无法从类的外部直接访问。
用途:private修饰符主要用于封装类的内部实现细节,隐藏那些不需要对外暴露的状态和行为。通过这种方式,可以提高类的安全性和可维护性。
internal
可见性:internal 修饰的类、接口、方法、属性、字段等只能在定义它们的同一个程序集(Assembly)(即同一个.cs文件中)内部被访问。如果尝试从另一个程序集访问它们,将会导致编译时错误。
用途:当你想要隐藏类的实现细节,但希望这些类在同一个程序集内的其他类之间是可用的,应该使用 internal 修饰符。这有助于封装和模块化,因为它减少了程序集间的依赖,并使得程序集内部的改动更加容易和安全。
对比
访问范围:public 的访问范围最广,可以在任何地方被访问;而 internal 的访问范围被限制在定义它的程序集内部。
使用场景:public 通常用于定义需要在多个程序集间共享的API或功能;而 internal 用于隐藏内部实现细节,减少不必要的外部依赖。
static(静态)
用途:static关键字用于声明属于类型本身而不是属于类型实例的静态成员(字段、方法、属性、事件等)。这意味着,无论创建了多少个类型的实例,静态成员都只有一份拷贝,并且这些实例共享这一份拷贝。
访问方式:静态成员通过类型本身来访问,而不是通过类型的实例。因此,你不需要创建类型的实例就可以访问静态成员。
生命周期:静态成员在程序启动时被加载到内存中,并且在程序运行时一直存在,直到程序结束。
注意事项:静态成员不能直接访问非静态成员,因为非静态成员属于类的实例,而静态成员属于类本身,不依赖于任何实例。
public(公共)
用途:public是一个访问修饰符,用于指定成员的访问级别。public成员可以在定义它们的程序集的任何地方被访问,无论是通过该类型的实例还是通过类型本身(对于静态成员)。
访问方式:public成员可以通过类型的实例或类型本身(对于静态成员)来访问,具体取决于成员是实例成员还是静态成员。
生命周期:public并不直接决定成员的生命周期;它只决定了成员的访问范围。成员的生命周期通常由它的类型(如值类型、引用类型)和上下文(如类成员、局部变量等)决定。
注意事项:将成员设为public意味着它们对外部是可见的,这可能会影响封装性。因此,在设计类时,应该谨慎地选择哪些成员应该是public的。
static和public一起使用
static和public可以一起使用,以声明一个公开的静态成员。这样的成员既可以通过类型本身来访问(因为它是静态的),也可以在定义它们的程序集的任何地方被访问(因为它是公开的)。
以下代码展示不同访问修饰符的区别和应用:
// PublicClass.cs public class PublicClass { public void PublicMethod() { // 这个方法可以在任何地方被调用 } internal void InternalMethod() { // 这个方法只能在同一个程序集内被调用 } } // AnotherClass.cs(位于同一程序集) class AnotherClass { void SomeMethod() { var publicClass = new PublicClass(); publicClass.PublicMethod(); // 可以调用 publicClass.InternalMethod(); // 也可以调用,因为它们在同一个程序集内 } } // 如果尝试从另一个程序集调用 InternalMethod,将会导致编译错误
class MyClass { private int myPrivateField; // 只能在MyClass内部访问 private void MyPrivateMethod() { // ... } }
代码如下:
//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("\n构造函数开始执行:"); // 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(); // Console.WriteLine("\n外部类1的实例化对象开始执行:"); // outer.ShowFields(); // 可以访问外部类1的public和internal成员 // // 尝试访问private成员会导致编译错误 // // Console.WriteLine($"PrivateField from Main: {outer.PrivateField}"); // 编译错误 // // 演示子类 // 子类1 子类1 = new 子类1(); // Console.WriteLine("\n子类1的实例化对象开始执行:"); // 子类1.ShowInheritedFields(); // 演示从外部类1继承的protected和protected internal成员的访问 // // 注意:由于Main在空间1命名空间中,所以它可以访问internal成员 // // 但如果Main在另一个命名空间中且不属于同一个程序集,则不能访问InternalField // // 保持控制台开启 // Console.WriteLine("Press any key to exit..."); // Console.ReadKey(); // } // } //} using System; // 定义一个命名空间MyNamespace namespace MyNamespace { // 定义一个公共类MyClass public class MyClass { // 私有字段,只能在MyClass内部访问 private int myPrivateField = 0; // 内部字段,只能在同一个程序集内的类访问 internal int myInternalField = 1; // 公共字段,可以在任何地方访问(只要MyClass是可访问的) public int myPublicField = 2; // 静态公共方法,可以在不创建MyClass实例的情况下调用,且可在任何地方访问(只要MyClass是可访问的) public static void MyStaticPublicMethod() { Console.WriteLine("This is a static public method."); Console.ReadKey(); } // 私有方法,只能在MyClass内部调用 private void MyPrivateMethod() { Console.WriteLine("This is a private method."); Console.ReadKey(); } // 内部方法,只能在同一个程序集内的类调用 internal void MyInternalMethod() { Console.WriteLine("This is an internal method."); Console.ReadKey(); } // 公共方法,可以在任何地方调用(只要MyClass是可访问的) public void MyPublicMethod() { Console.WriteLine("This is a public method."); Console.ReadKey(); // 调用私有方法和内部方法(这些调用仅在MyClass内部有效) MyPrivateMethod(); MyInternalMethod(); // 直接访问字段 Console.WriteLine($"Public Field: {myPublicField}"); Console.ReadKey(); // 注意:这里不能直接访问myPrivateField和myInternalField,因为它们的访问级别不允许 // 调用静态方法(不需要实例) MyStaticPublicMethod(); } } // 同一个命名空间内的另一个类,用于演示内部成员的访问 internal class MyOtherClass { public void AccessInternalMembers() { var myClass = new MyClass(); // 可以访问内部字段和方法,因为它们在同一个程序集内 Console.WriteLine($"Internal Field: {myClass.myInternalField}"); myClass.MyInternalMethod(); // 但不能访问私有字段和方法,因为它们的访问级别不允许 // myClass.myPrivateField; // 编译错误 // myClass.MyPrivateMethod(); // 编译错误 } } class Program { static void Main(string[] args) { // 调用静态公共方法 MyClass.MyStaticPublicMethod(); // 创建MyClass的实例并调用公共方法 var myClass = new MyClass(); myClass.MyPublicMethod(); // 访问MyOtherClass的实例以演示内部成员的访问 var myOtherClass = new MyOtherClass(); myOtherClass.AccessInternalMembers(); // 尝试直接访问私有和内部成员(这些会导致编译错误) // Console.WriteLine(myClass.myPrivateField); // 编译错误 // Console.WriteLine(myClass.myInternalField); // 编译错误,除非在MyOtherClass中 // myClass.MyPrivateMethod(); // 编译错误 // 注意:在Main方法中,我们不能直接访问myInternalField,因为它不是public的 } } }
以下为官方代码:
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(); } }
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/127008.html